Skip to main content

Command Palette

Search for a command to run...

07/30 - 30 dias de HackerRank

Updated
•4 min read•View as Markdown
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:

  1. Iterar pela lista de notas que a função vai receber;
  2. Verificar se o valor da $nota$ é menor que $40$;
  3. Se for, adicionar o valor da $nota$ na lista atualizada de notas;
  4. Se não for, calcular o próximo múltiplo de $5$ da $nota$ atual;
  5. Verificar se a diferença entre o próximo múltiplo e a $nota$ atual é menor que $3$;
  6. Se for, adicionar o valor do múltiplo de $5$ na lista de notas atualizadas;
  7. Se não, retornar a própria $nota$ na lista atualizada;
  8. 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.

image.png

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!

image.png

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

More from this blog

Lucas Nabesima

22 posts