I’ve challenged myself to 30 days of codewars, one a day, time myself, and learn how I could have done it better.
Today I did: https://www.codewars.com/kata/prize-draw/
Time: 60 minutes
What I’ve learnt: So I was super surprised that this one took me an hour (with some breaks in between doing other stuff)! But I was really thinking of a way to store the winner, before I full read the kata I thought I was just storing one winner so I wanted to create an array of the winner, so as I iterated I could store the highest scoring winner along with their name, so I tried
array[0], array[1] = <name>, <score>
and sadly that did not work (it works in ruby!). So then I changed it to `array = [<name>, <score>]`, and that worked, but then I realized I need all the names in order so I could choose the n number of them and return that one.
Sooooo, I decided an array of objects is my best bet, and tried this array.push({name: score}), only to realize that I can’t use a variable name as a key in the object like that. So again learning new things. (And this sounded like an easy kata lol). So the way to do that was to put a bracket around name: {[name]: score}, but by then I had already changed my mind and thought it would look cleaner (and easier to sort!) if I named it like this: `array.push({name: <name>, score: <score>})`.
So now after a for loop
, split("")
, reduce
, with charCodeAt -96
(all the letters were converted `toLowerCase()`, and then * by the `weight[i]` I had my `score` (and name was from the array.split("")[i]
) to push in the winners array.
Now I created a variable and did `winners.sort(a, b => a.score > b.score)`, and it was interesting to see that sort mutated the winners array, so got rid of the variable and continued using the mutated array. So I first sorted by name, and then by score, and all was good in the world until I got to the final tests, and the random tests were failing. And for some reason, my arrays were not all being sorted :(.
[ { name: ‘Olivia’, score: 444 },
{ name: ‘Elizabeth’, score: 485 },
{ name: ‘Matthew’, score: 485 },
{ name: ‘Lagon’, score: 162 },
{ name: ‘Addison’, score: 365 },
{ name: ‘Robert’, score: 420 },
{ name: ‘Olivai’, score: 444 },
{ name: ‘Lily’, score: 372 },
{ name: ‘Lyli’, score: 310 },
{ name: ‘William’, score: 344 },
{ name: ‘Willaim’, score: 344 },
{ name: ‘Noah’, score: 84 },
{ name: ‘Grace’, score: 156 },
{ name: ‘Abigail’, score: 288 },
{ name: ‘Sofia’, score: 165 },
{ name: ‘Madison’, score: 328 },
{ name: ‘Sophia’, score: 148 },
{ name: ‘Liam’, score: 117 },
{ name: ‘Ava’, score: 108 },
{ name: ‘Avery’, score: 76 },
{ name: ‘James’, score: 53 },
{ name: ‘Daniel’, score: 51 },
{ name: ‘Aiden’, score: 38 } ]
So I had to get a better sort going, though I am not really sure why this didn’t work on the random tests, but the initial tests it was fine on. So I literally returned where each position should go based on if statements:
1
2
3
4
5
6
|
winners.sort((a,b) => {
if (a.score == b.score) return a.name.toLowerCase() > b.name.toLowerCase()
if (a.score < b.score) return 1
if (a.score > b.score) return -1;
return 0;
})
|
And then returned the winners[n-1].name and we were flying green!!!
So I think I’ve learned about objects, and sort in this lab. Though I will need to follow up why the built in did not work for me.
What I learned from other people’s code:
So I did see that people did have to hack into their sort method. I’ve gotta say I’m pretty happy with my solution overall, and see I did not overcomplicate things. It’s interesting to note how in some people’s sort() they use a.score – b.score. This will return either a positive or negative number so that will tell it where to place it. Very nice! (Here’s a nice link on sorts – http://www.javascriptkit.com/javatutors/arraysort.shtml)
Happy learning until tomorrow!