# 05/30 - 30 dias de HackerRank

Mais um dia, mais um desafio. Esse aqui tem um problema divertido para resolver.


> ## [Birthday Cake Candles](https://www.hackerrank.com/challenges/birthday-cake-candles/problem)
> 
> Você está encarregado do bolo de uma festa de aniversário de uma criança. Você decidiu que o bolo vai ter uma vela para cada ano que a criança tem. Ela só vai conseguir soprar as velas mais altas. Conte quantas das velas são as mais altas.
> 
> **Exemplo**:
> <br/>
> \\(candles = [ 4, 4, 1, 3 ]\\)
> 
> A altura máxima das velas é de \\(4\\) unidades. Há duas delas, então retorne \\(2\\).


Esse é mais um dos desafios que você olha, para e fica pensando "mas como que eu vou fazer esse troço?". Mas ao quebrar o problema em pedaços menores, ele acaba ficando menos complexo. Então, o que é necessário para resolver esse problema?

1. Descobrir qual o maior número dentro da *array* \\(candles\\);
2. Contar quantas vezes esse número se repete dentro dessa lista;
3. Retornar o montante acumulado.

Como podemos executar o primeiro passo? Um dos caminhos seria ordenar a array (usando o método [sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)) e pegar o último valor da *array* ordenada. Contudo, existe uma função que retorna esse mesmo valor, com menos esforço: a função [`Math.max()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max).

Esse função retorna o número com o valor mais alto dentre os argumentos informados, mas ela não aceita *arrays* como argumentos. Então precisamos desestruturar a lista... Para isso, usamos o [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)(...), que "abrirá" a *array* dentro da função.

```JS
function birthdayCakeCandles(candles) {
  const max = Math.max(...candles); //4
} 
```

Com isso resolvido, precisamos descobrir como contar quantas vezes esse valor se repete. <br />
Poderíamos usar um laço `for` pra isso, mas como vamos retornar um valor acumulado no final, o método [`reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) parece ser mais adequado.


```JS
function birthdayCakeCandles(candles) {
  const max = Math.max(...candles);

  const count = candles.reduce((acc, cur) => {
    cur === max && acc++;
    return acc;
  }, 0);

  return count;
}
```

A cada volta do `callback` do método `reduce`, a função verifica se o valor atual (`cur`) é igual ao valor máximo do *array* (armazenado em `max`). Caso seja, o valor da contagem (`acc`) é incrementado em \\(1\\).<br />
Ao final dos elementos, a contagem é retornada pelo método e armazenada na variável `count`, que, por fim, é retornada pela função.

Agora, é só rodar os testes para ver se a nossa lógica está certa!

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1667660651725/7Qj8y8EwI.png align="center")

Deu tudo certo! 🥳 <br />
Até o próximo desafio!

