4
\$\begingroup\$

I was having fun on solving one of the HackerRank simple challenges - Birthday Cake Candles.


Description

Colleen is turning n years old! Therefore, she has n candles of various heights on her cake, and candle i has heighti. Because the taller candles tower over the shorter ones, Colleen can only blow out the tallest candles.

Given the heighti for each individual candle, find and print the number of candles she can successfully blow out.


Input Format

The first line contains a single integer, , denoting the number of candles on the cake. The second line contains space-separated integers, where each integer describes the height of candle .


Output Format

Print the number of candles Colleen blows out on a new line.


Sample Input 0

4
3 2 1 3

Sample Output 0

2

Explanation 0

We have one candle of height 1, one candle of height 2, and two candles of height 3. Colleen only blows out the tallest candles, meaning the candles where height=3. Because there are 2 such candles, we print 2 on a new line.


My solution to the exercise above. You can find full code in gist with full code

function birthdayCakeCandles(n, ar) {
  var counts = {};

  ar.forEach(function(x) {
      counts[x] = (counts[x] || 0) + 1;
  });

  var toAr = Object.keys(counts).map(function(key){ return counts[key]; });
  var result = Math.max.apply(Math, toAr);

  return result;
}
  • n - number of candles
  • ar - array with heights of the candles

I would like to get a feedback on my part of the code, as I guess I might do a lot of unnecessary steps.

\$\endgroup\$

2 Answers 2

6
\$\begingroup\$

The algorithm is to count the number of elements in the array that are equal to the max of the array. Let the code express that. Both the original code and the procedural accepted answer are a clutter of bookkeeping details.

function birthdayCakeCandles(n, ar) {
    const max = Math.max(...ar)
    return ar.filter(x => x === max).length
}
\$\endgroup\$
5
  • \$\begingroup\$ With ES6 Math.max(...ar). \$\endgroup\$
    – Tushar
    Jul 14, 2017 at 4:08
  • \$\begingroup\$ @Tushar good point. updated to use that suggestion. \$\endgroup\$
    – Jonah
    Jul 14, 2017 at 4:15
  • \$\begingroup\$ @Jonah Thank you for your answer. This is a seriously clean way of doing this. \$\endgroup\$
    – ummahusla
    Jul 14, 2017 at 6:24
  • \$\begingroup\$ Any idea why ar.filter(x => x === Math.max(...ar)).length doesn't pass all the tests? \$\endgroup\$
    – kldavis4
    Feb 6, 2019 at 19:07
  • 1
    \$\begingroup\$ @kldavis4 It's recalculating the max for every elements of the array, and so has O(n^2) vs O(n). It would timeout on any tests with large inputs. Hacker rank often explicitly adds these to force you to use an efficient algorithm. \$\endgroup\$
    – Jonah
    Feb 6, 2019 at 22:02
4
\$\begingroup\$

Depending what you are after, the following only iterates the array once, I think you will iterate 3 times above.

function birthdayCakeCandles(n, ar) {
  let largest = 0;
  let counts = {};
  for(let i=0; i< ar.length; i++) {
    let num = ar[i];
    if (num > largest) largest = num;
    counts[num] = (counts[num] || 0) + 1 
  }
  return counts[largest];
}
\$\endgroup\$
1
  • \$\begingroup\$ Thank you for your answer, clearly cleaner answer than I have. \$\endgroup\$
    – ummahusla
    Jul 14, 2017 at 6:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.