Sorry, a bit late today. Had my last day of work before the Christmas weekend, and I was on the road for a lot of the day. Christmas Eve Eve! So excited!
The Puzzle
In today’s puzzle, that crab that we taught how to play cards has decided to teach us a game involving cups. It's apparently a very clever crab. Given cups labeled in a specific order, they are shuffled around based on an algorithm. Our job is to keep track of them and not to let the crab hustle us.
The Leaderboards
As always, this is the spot where I’ll plug any leaderboard codes shared from the community.
Ryan's Leaderboard: 224198-25048a19
If you want to generate your own leaderboard and signal boost it a little bit, send it to me either in a DEV message or in a comment on one of these posts and I'll add it to the list above.
Yesterday’s Languages
Updated 08:54PM 12/23/2020 PST.
Language | Count |
---|---|
Python | 2 |
Haskell | 1 |
Rust | 1 |
JavaScript | 1 |
TypeScript | 1 |
Merry Coding!
Top comments (6)
Ok so I'll be the first to emit that while my part one was fine in Haskell it was never going to scale to part 2! I really hate mutable arrays in Haskell, I mean what's the point, and as such I wrote the 2nd part in rust.
Here's Haskell for part 1:
and here's Rust for part 2:
A bit of linked list action in python. This can be optimized further because the dict only contains continuous numbers (other than 0) so we shouldn't need: a dict whose key is the cup value, and where each entry is a node containing the next cup. Instead we can have a list whose index is the cup value and where each entry contains the next cup. The two are basically equivalent, but the list is faster.
This was an amazing problem. A naive approach gives absolutely terrible performance and memory characteristics in any language, and the best approach is amazingly fast. I landed somewhere in the middle.
I started in Rust of course, with a naive approach of building new vectors for each move:
My estimate is this was going to take 20-24h to run part 2 however. So I switched to linked lists. In Rust's strict ownership model this is pretty tricky and an exercise for another day so I switched to C:
There is an even simpler approach however which I didn't realise until later. Each cup can be modelled by simply the index to the next cup. So you just need one huge vector of indices - each cup can be found by id by looking up a position in the vector, and the ordering can be adjusted by reassigning next indices just like how the linked list works. I'll aim to do that in Rust.
And here we are. Setting up the initial array was the hardest bit. And it's faster than the C pointer version.
Little late to finish this one, but I did it and I'm happy with it even if the memory usage might be atrocious.
My JavaScript video walkthrough: