07/30 - 30 dias de HackerRank

Mais um desafio de cunho prático! Eu fico feliz que estamos saindo da esfera da abstração e indo para aplicações práticas das tecnologias, pra mostrar que programação pode ajudar no dia-a-dia também!
Grading Students
Sam é um professor em uma universidade que tem as seguintes políticas para avaliação dos alunos:
- Todo aluno recebe uma $nota$ que vai de $0$ a $100$;
- Toda $nota$ abaixo de $40$ reprova o aluno.
Sam gosta de arredondar as $notas$ dos alunos seguindo as regras abaixo:
- Se a diferença da $nota$ e seu próximo múltiplo de $5$ for menor que $3$, a nota será arredondada para o próximo múltiplo de $5$;
- Se o valor da $nota$ for menor que $38$, ela não será arredondada, pois mesmo que arredonde ainda será uma nota de reprovação.
Seguindo essas regras, escreva uma função que automatize o processo de arredondamento.
Para ajudar nosso amigo Sam, podemos seguir os seguintes passos:
- Iterar pela lista de notas que a função vai receber;
- Verificar se o valor da $nota$ é menor que $40$;
- Se for, adicionar o valor da $nota$ na lista atualizada de notas;
- Se não for, calcular o próximo múltiplo de $5$ da $nota$ atual;
- Verificar se a diferença entre o próximo múltiplo e a $nota$ atual é menor que $3$;
- Se for, adicionar o valor do múltiplo de $5$ na lista de notas atualizadas;
- Se não, retornar a própria $nota$ na lista atualizada;
- Retornar a lista atualizadas de notas.
Como vamos retornar uma array nova ao final da função, que contém todas as notas atualizadas, podemos usar o método map(). Ele itera por todos os elementos do vetor e retorna uma nova lista, com os elementos retornados pela função de callback.
O método forEach(), em contrapartida, apenas executa uma função para cada elemento do array, sem retornar uma nova lista.
Já podemos fazer a verificação das notas de reprovação agora, assim já matamos dois passos de uma vez!
const grades = [73, 67, 38, 33];
function gradingStudents(grades) {
const result = grades.map(grade => {
if (grade < 38) return grade;
});
return result; //[undefined, undefined, undefined, 33]
}
Definimos a variável result e aplicamos o método map(), fazendo uma verificação se o elemento atual (grade) é menor que $38$, conforme a regra indicada. Caso seja, ele será retornado pelo callback. A array fornecida só tem uma $nota$ abaixo de $38$, por isso só um valor foi retornado.
Os demais itens retornaram undefined, já que não definimos um retorno para o caso da $nota$ ser maior que $38$.
O próximo passo, então, é fazer o cálculo do próximo múltiplo de 5 da nota. Para isso, vamos usar a função Math.ceil(), que retorna o número decimal passado como argumento arredondado para cima.
const grades = [73, 67, 38, 33];
function gradingStudents(grades) {
const result = grades.map(grade => {
if (grade < 38) return grade;
const roundedGrade = Math.ceil(grade / 5) * 5;
});
return result; //[undefined, undefined, undefined, 33]
}
Agora fazemos o cálculo das notas arredondadas. Para isso passamos o resultado da divisão entre a nota atual e $5$ para a função Math.ceil() e, esse resultado é multiplicado por 5. Esse resultado é o próximo múltiplo de $5$.
Da primeira vez que eu olhei para essa função, eu entendi que ela funcionava mas não entendi como ela funcionava. Desenhar o passo a passo (assim como a imagem abaixo) me ajudou a elucidar a questão.

A função continua retornando a array com elementos não definidos porque não fizemos nenhuma comparação a mais ou alteramos o retorno, somente fizemos o cálculo do próximo múltiplo. Podemos agora adicionar o retorno do map(), verificando se a diferença entre a nota arredondada e a nota original é menor que três.
const grades = [73, 67, 38, 33];
function gradingStudents(grades) {
const result = grades.map(grade => {
if (grade < 38) return grade;
const roundedGrade = Math.ceil(grade / 5) * 5;
return roundedGrade - grade < 3 ? roundedGrade : grade
});
return result; //[ 75, 67, 40, 33 ]
}
Caso a diferença for menor que 3, a nota arredondada será inserida na lista. Caso for maior, a nota a ser inserida é original. Para reduzir a quantidade de código escrito, usei o operador ternário ?ao invés de um bloco if... else, mas o resultado de ambas as opções é o mesmo.
O que nos resta agora é testar para validar nosso código!

Totalmente excelente! 👍👍 Até o próximo desafio!



