3
\$\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\$
5
\$\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\$
  • \$\begingroup\$ With ES6 Math.max(...ar). \$\endgroup\$ – Tushar Jul 14 '17 at 4:08
  • \$\begingroup\$ @Tushar good point. updated to use that suggestion. \$\endgroup\$ – Jonah Jul 14 '17 at 4:15
  • \$\begingroup\$ @Jonah Thank you for your answer. This is a seriously clean way of doing this. \$\endgroup\$ – ummahusla Jul 14 '17 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 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 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\$
  • \$\begingroup\$ Thank you for your answer, clearly cleaner answer than I have. \$\endgroup\$ – ummahusla Jul 14 '17 at 6:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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