This year I participated the first time in the Advent of Code, a series of programming puzzles before Christmas. This post is an experience report of my 25+ day journey in December.
Spoiler alert: If you’re still working or planning to work on the puzzles stop reading now.
From December 1 to December 25, a programming puzzle appears each day at Advent of Code website. To understand each day’s two-part puzzle, go to the website and read the full description (for example Day 1: Report Repair).
I decided to write all solutions in Rust because I wanted to learn the language. This was my only “hard” requirement, the rest was just to have fun. After solving the first couple of puzzles I set the following boundaries for myself:
I also decided what were not my goals:
Variations on Conway’s Game of Life appeared on multiple days: on day 11 the cells evolved on a fixed grid, on day 17 in three and four dimensions, and on day 24 the solution was expected on a hexagonal grid. I enjoyed these problems and learned a lot about Rust iterators and iterator adapters.
Day 18 was about a small expression evaluator with custom precedence and associativity rules. I learned about Dijkstra’s shunting yard algorithm and I used it to transform the expressions specified in infix notation to reverse Polish notation.
The second part of the puzzle on day 13 caused me headaches. Someone on a Reddit thread suggested that the Chinese remainder theorem is relevant here. I learned the basics of this theorem and recognized how to use it in the solution.
Day 10 took me multiple days to finish. I failed recognize that relevant strategy to solve this puzzle was dynamic programming on which I even wrote an article. Perhaps I should read it again…
There were also days when the problem itself was not particularly difficult, but I still struggled. On these days I ended up with code that sort of works, but not particularly nice:
Solving these puzzles was great for learning Rust. From these last three weeks I’d underline these topics:
countalmost every day. Long iterator chains take a bit of getting used to, but they are idiomatic in Rust.
multi_cartesian_productfrom the itertools crate was a life-saver for implementing Game of Life in arbitrary dimensions.
enumis a real sum type where the variants can contain data too. I used an
enumas a central type on days 4, 8, 14, 18 and 19.
Completing the Advent of Code and learning a new programming language was challenging. I learned a lot in these last 25 days about puzzles, algorithms and about the Rust language.
I particularly enjoyed the puzzles where knowing an algorithm is rewarding and makes your code concise and readable. When my code is long and messy I know that I’m missing something: a data structure, an algorithm or a language feature. The hard part is to figure out which one.
The source code of all solutions are available on GitHub.
Thanks Eric Wastl for creating and running Advent of Code.