{"id":18187840,"url":"https://github.com/0bvim/milenio_challenge","last_synced_at":"2026-02-04T03:37:14.749Z","repository":{"id":248622568,"uuid":"829210673","full_name":"0bvim/milenio_challenge","owner":"0bvim","description":"Share objects, container and tests","archived":false,"fork":false,"pushed_at":"2024-07-16T23:03:23.000Z","size":246,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-01T12:10:53.094Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0bvim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-16T01:40:02.000Z","updated_at":"2024-08-07T02:19:54.000Z","dependencies_parsed_at":"2024-08-07T07:13:34.947Z","dependency_job_id":"3aa6d229-22d6-4b49-93d8-98f6e2e4edbd","html_url":"https://github.com/0bvim/milenio_challenge","commit_stats":null,"previous_names":["0bvim/milenio_challenge"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/0bvim/milenio_challenge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0bvim%2Fmilenio_challenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0bvim%2Fmilenio_challenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0bvim%2Fmilenio_challenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0bvim%2Fmilenio_challenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0bvim","download_url":"https://codeload.github.com/0bvim/milenio_challenge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0bvim%2Fmilenio_challenge/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264696307,"owners_count":23650936,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-03T02:03:30.423Z","updated_at":"2026-02-04T03:37:09.723Z","avatar_url":"https://github.com/0bvim.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Processador de CSV\n\nEste desafio visa avaliar suas habilidades técnicas e capacidade de solucionar problemas reais, desenvolvendo uma biblioteca compartilhada ou _shared object_ (.so) que será utilizada por uma aplicação em C.\n\n## Objetivo\n\nImplementar uma biblioteca que processe arquivos CSV, aplicando filtros e selecionando colunas conforme especificado. A solução deve ser capaz de integrar com a interface definida em C abaixo.\n\n```c\n/**\n * Process the CSV data by applying filters and selecting columns.\n *\n * @param csv The CSV data to be processed.\n * @param selectedColumns The columns to be selected from the CSV data.\n * @param rowFilterDefinitions The filters to be applied to the CSV data.\n *\n * @return void\n */\nvoid processCsv(const char[], const char[], const char[]);\n\n/**\n * Process the CSV file by applying filters and selecting columns.\n *\n * @param csvFilePath The path to the CSV file to be processed.\n * @param selectedColumns The columns to be selected from the CSV data.\n * @param rowFilterDefinitions The filters to be applied to the CSV data.\n *\n * @return void\n */\nvoid processCsvFile(const char[], const char[], const char[]);\n```\nprocessCsv\n- csv: String com os dados do CSV, onde cada linha representa um registro e as colunas são separadas por vírgulas.\n    - Exemplo: `\"header1,header2,header3\\n1,2,3\\n4,5,6\"`\n- selectedColumns: Uma string onde os nomes das colunas a serem selecionadas são separados por vírgulas.\n    - Exemplo: `\"header1,header3\"`\n- rowFilterDefinitions: Uma string onde cada filtro é definido em uma nova linha, no formato `header(comparador)valor`.\n    - Exemplo: `\"header1\u003e1\\nheader2=2\\nheader3\u003c6\"`\n\nprocessCsvFile\n- csvFilePath: String com o caminho do arquivo CSV.\n    - Exemplo: `\"path/to/csv_file.csv\"`\n- selectedColumns: Uma string onde os nomes das colunas a serem selecionadas são separados por vírgulas.\n    - Exemplo: `\"header1,header3\"`\n- rowFilterDefinitions: Uma string onde cada filtro é definido em uma nova linha, no formato `header(comparador)valor`.\n    - Exemplo: `\"header1\u003e1\\nheader2=2\\nheader3\u003c6\"`\n\n\nExemplo:\n\n```c\nconst char csv[] = \"header1,header2,header3\\n1,2,3\\n4,5,6\\n7,8,9\";\nprocessCsv(csv, \"header1,header3\", \"header1\u003e1\\nheader3\u003c8\");\n\n// output\n// header1,header3\n// 4,6\n\nconst char csv_file[] = \"path/to/csv_file.csv\";\nprocessCsvFile(csv_file, \"header1,header3\", \"header1\u003e1\\nheader3\u003c8\");\n\n// output\n// header1,header3\n// 4,6\n```\n\n## Funcionalidades Obrigatórias e Requisitos\n\n\nO candidato deve focar nos requisitos obrigatórios, pois o descumprimento de qualquer um deles acarreta na desclassificação do processo seletivo.\n\nPara os exemplos abaixo, considere sempre o seguinte CSV:\n\n```csv\nheader1,header2,header3\n1,2,3\n4,5,6\n7,8,9\n```\n\n- **O CSV processado deve ser escrito no stdout**\n\n- **A primeira linha do CSV sempre será um header**\n\n- **O CSV processado deverá incluir o header do CSV considerando a seleção de coluna**\n\n- **A sua implementação deve tratar CSVs com quantidades arbitrárias de caractéres**\n\n- **A sua implementação deve tratar CSVs onde as colunas tem quantidades arbitrárias de caractéres**\n\n- **Uma string de seleção de colunas vazia é equivalente a selecionar todas as colunas**\n\n- **No mínimo, o candidato deve implementar filtros para maior (\u003e), menor (\u003c) e igual (=)**\n\n- **As strings de seleção de colunas e filtro sempre terão a mesma ordem que aparecem no CSV**\n\n    Exemplo:\n    - `\"header1,header3\"` ou `\"header1=4\\nheader3\u003e3\"` \u0026rarr; OK\n    - `\"header3,header1\"` ou `\"header3\u003e3\\nheader1=4\"` \u0026rarr; NÃO OK\n\n- **Vírgulas sempre delimitam uma coluna, aspas não têm nenhuma interpretação especial**\n\n    Exemplo: No CSV abaixo, o nome da primeira coluna é `'hea\"der1'`\n\n    ```csv\n    hea\"der1,header2,header3\n    1,2,3\n    ```\n\n- **Apenas linhas que condizem com todos os filtros devem ser selecionadas**\n\n    Exemplo: Aplicando os filtros `\"header1=4\\nheader2\u003e3\"` e selecionando as colunas header1 e header3. Somente a linha 4,5,6 `(header1 = 4 AND header2 \u003e 3)` deve ser selecionada, pois todas as condições dos filtros devem ser atendidas. Output do filtro abaixo:\n\n    ```csv\n    header1,header3\n    4,6\n    ```\n\n- **Nunca serão fornecidos filtros inválidos ou colunas inexistentes**\n\n    Exemplo:\n    - Coluna inexistente: `\"header4\"`\n    - Filtro inválido: `\"header1#2\"`\n\n- **Nunca será fornecido mais de 1 filtro por coluna**\n\n    Exemplo: Se o filtro for `\"header1=2\"`, não haverá outro filtro para `\"header1\"` na mesma operação.\n\n- **O CSV de entrada terá no máximo 256 colunas**\n\n- **O nome de cada coluna é único**\n\n- **Os comparadores nos filtros devem seguir a ordem lexicográfica conforme a implementação da [strcmp](https://www.man7.org/linux/man-pages/man3/strcmp.3.html) da stdlibc**\n\n- **A arquitetura alvo é x86_64**\n\n- **Não é permitida a execução de processos externos. Seu código não deve usar chamadas de sistema para executar outros programas**\n\n- **Não é permitido o uso de bibliotecas externas para converter o CSV em estruturas de dados intermediárias (libs de lexers e tokenizers podem ser utilizadas)**\n\n\n## Funcionalidades Bônus\n\nSe o candidato terminar todos os pontos obrigatórios e ainda dispor de tempo livre, a seguir estão algumas funcionalidades bônus que contarão como critério de desempate.\n\nPara todos os exemplos abaixo, considere sempre o seguinte CSV:\n```csv\nheader1,header2,header3\n1,2,3\n4,5,6\n7,8,9\n```\n\n1) **Desenvolver testes unitários**\n2) **As colunas que aparecem na string de colunas selecionadas podem estar em ordem arbitrária**\n    Exemplo: Se a string de colunas selecionadas é `\"header3,header1\"`, sua implementação deve selecionar as colunas nesta ordem.\n\n    ```csv\n    header1,header2,header3\n    1,2,3\n    4,5,6\n    7,8,9\n    ```\n\n    E a string de colunas selecionadas: `\"header3,header1\"`, o resultado deve ser:\n\n    ```csv\n    header1, header3\n    1,3\n    4,6\n    7,9\n    ```\n\n3) **As colunas na string de filtros podem aparecer em ordem arbitrária**\n\n    Se os filtros são fornecidos como `\"header2\u003e3\\nheader1=4\"`, sua implementação deve aplicar esses filtros corretamente, independentemente da ordem, conforme output abaixo:\n\n    ```csv\n    header1,header2,header3\n    4,5,6\n    ```\n\n4) **Colunas que não existem podem aparecer na seleção de colunas e nos filtros**\n\n    Se a string de colunas selecionadas inclui `\"header4\"` e o CSV não tem um header header4, ou se os filtros incluem `\"header5=10\"` e o CSV não tem um header header5, sua implementação deve tratar esses casos adequadamente, escrevendo no stderr com a mensagem `\"Header 'header4' not found in CSV file/string\"` ou `\"Header 'header5' not found in CSV file/string\"`, respectivamente, encerrando a execução.\n\n\n5) **Tratamento de erro para filtros inválidos**\n\n    Se for fornecido um filtro inexistente ou inválido, como `header1#2`, sua implementação deve tratar esses casos escrevendo no stderr com a mensagem `\"Invalid filter: 'header1#2'\"`.\n\n6) **Aceitar mais de 1 filtro por header**\n\n    Permitir que múltiplos filtros sejam aplicados a um mesmo header, como `\"header1=1\\nheader1=4\\nheader2\u003e3\\nheader3\u003e4\"`, e tratar esses filtros de forma adequada. Para essa implementação, o candidato deverá implementar a lógica OR para filtros no mesmo header.\n    O filtro de exemplo será considerado como: `(header1=1 OR header1=4) AND header2\u003e3 AND header3\u003e4`, resultando no output abaixo:\n\n    ```csv\n    header1,header2,header3\n    4,5,6\n    ```\n\n7) **Implementar os operadores diferente (!=), Maior ou igual que (\u003e=), e Menor ou igual que (\u003c=)**\n\n    Permitir que filtros utilizem operadores de diferença, maior ou igual, e menor ou igual, como `\"header1!=2\\nheader2\u003e=5\\nheader3\u003c=6\"`, e tratar esses filtros de forma adequada resultando no output abaixo:\n\n    ```csv\n    header1,header2,header3\n    4,5,6\n    ```\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0bvim%2Fmilenio_challenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0bvim%2Fmilenio_challenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0bvim%2Fmilenio_challenge/lists"}