This coding puzzle is incredible
This is such a tricky coding puzzle, you won’t believe the algorithm I had to make to solve it.
function addToLeaderboard(player, ranked) { }
// Can you write the code for the addToLeaderboard() function?
console.log(addToLeaderboard([80, 60, 60, 10], [90])); // [1]
console.log(addToLeaderboard([80, 60, 60, 10], [90, 100])); // [2, 1]
console.log(
addToLeaderboard([80, 60, 60, 10], [90, 60, 5]) // [1, 3, 5]
);
So first let’s understand what the puzzle is about.
You have a function that takes two inputs:
- a
player
array — a list of player scores - a
ranked
array — a list of scores already on the leaderboard
So each of the scores in ranked
are ranked.
For example:
- Player scores: 80, 60, 10
- Resulting ranking: 1, 2, 3 — respectively
Ignoring how bad you have to be get 10 in any sort of game where others are scoring 80…
What if the players what if the players are tied? For example:
- 80, 60, 60, 10
Result ranking:
- 1, 2, 2, 3
You give the same rank to the tied players, and then the next players get the rank after that.
So what does the function do? It adds the new batch of scores in player
to the leaderboard in ranked
— which ranks them
The function will return an array of the new ranks of these new scores that just got added.
For example if the player array is [90]
— just one item, it will return [1]
— the scores are now 90, 80, 60, 10.
So if the array is [90, 60, 5]
, what will it return?
It will be [1, 3, 5]
— NOT [1, 2, 4]
or [1, 2, 5]
like you might mistakenly guess.
So this is where we are:
function addToLeaderboard(ranked, players) {
}
console.log(addToLeaderboard([80, 60, 60, 10], [90])); // [1]
console.log(addToLeaderboard([80, 60, 60, 10], [90, 100])); // [2, 1]
console.log(
addToLeaderboard([80, 60, 60, 10], [90, 60, 5]) // [1, 3, 5]
);
So how we go about it? How do we get the ranks of the newly added scores.
I can see that data from both arrays are being combine into each other to give the updated leaderboard data.
You can also see that this is a leaderboard of scores — which clearly means sorting is going on…
Can you see where this is going?
Initially, I thought it was going to be a highly sophisticated algorithm.
But after this simple thought exercise, what we need to do is so obvious.
- Merge the
player
andranked
arrays. - Sort the result of the new array
- Get the position of each score in
player
from the sorted array
Let’s merge the arrays:
// ranked: 80, 60, 10
// players: 90, 60, 5
const merged = [...ranked, ...players];
// merged: 80, 60, 10, 90, 60, 5
Now sorting — since the highest score comes first, we need to sort it by descending order:
const sorted = merged.sort((a, b) => b - a);
// sorted: 80
How about getting the positions for each score from player
in the new leaderboard?
Of course we have the indexOf()
method.
But if you just used this you’d be way off the mark… (get it?)
indexOf
returns the zero-based index — first element has index of 0
, second of 1
, and so on…
const rank = sorted.indexOf(players[0]); // 0
To get the leaderboard ranks, we need the one-based index — first element should give 1
.
So obviously we fix easily with a +1
.
const rank = sorted.indexOf(players[0]) + 1; // 1
So what’s left now is doing this for each item in the players
array — a perfect use case for… ?
map():
const ranks = players.map(
(score) => sorted.indexOf(score) + 1
);
So now let’s test the full function:
function addToLeaderboard(ranked, players) {
const merged = [...ranked, ...players];
const sorted = merged.sort((a, b) => b - a);
const ranks = players.map(
(score) => sorted.indexOf(score) + 1
);
return ranks;
}
console.log(addToLeaderboard([80, 60, 60, 10], [90])); // [1]
console.log(addToLeaderboard([80, 60, 60, 10], [90, 100])); // [2, 1]
console.log(
addToLeaderboard([80, 60, 60, 10], [90, 60, 5]) // [1, 3, 5]
);
If it works we should get the results in the comments:

No! What happened with the last test case?
It’s giving [1, 3, 7]
instead of [1, 3, 5]
?
It seems like the last score (5) is being pushed down by 2 from 5 to 7?
What do you think could be causing this?
Yes! The multiple 60
‘s in the array is affecting the result that indexOf
gives.
To fix this we need to remove the duplicates after the merge.
A perfect job for Set()
:
function addToLeaderboard(ranked, players) {
const merged = [...ranked, ...players];
const unique = [...new Set(merged)];
const sorted = unique.sort((a, b) => b - a);
const ranks = players.map(
(score) => sorted.indexOf(score) + 1
);
return ranks;
}
Now let’s try that again:

Perfect.