On TWIT, my favourite general tech podcast, the presenter mentioned the Advent of Code. This is an annual event that runs from 1 to 25 December. Each day, a new puzzle is revealed, which usually requires a programming solution. You only have to submit a solution not how you solved the two daily questions.
The TWIT presenter, Leo Laporte, said that the puzzles get progressively harder and that by day 10 he drops out. The puzzles vary in difficulty. Puzzles that are difficult for some people could be easy for others. I took it as an opportunity to challenge myself since I rarely program nowadays and have certainly forgotten most of the computer science I learnt at university. I didn’t expect to complete all 25 days.
The puzzles are revealed at 5am (UK time). Although there are no prizes for solving the puzzles, every day, the first 100 people to solve the puzzle receive points. So there is a competitive element amongst elite programmers around the world. I learnt that there is such a thing as a competitive programmer. These people have honed their skills through study and competition. Puzzles that can take hours for mortals to solve are solved by these competitive programmers in minutes. Some of them stream videos, on Twitch and YouTube, of themselves solving the puzzles.
I was looking, recreationally, at doing some mobile app development using a framework called Flutter. The programming language for that is a relatively new language called Dart. Solving puzzles is a good way of learning a programming language and some people use Advent of Code for that purpose. I decided that would be a fun way of learning Dart.
My solutions, the source code, are here.
Each day (apart from the last) the puzzles are alliteratively titled. Here’s a summary of each day. This is more for my own record of the event!
Day 1: Report Repair
The puzzles are linked by a story that runs for 25 days. The first day, unsurprisingly, starts easy.
Day 2: Password Philosophy
This was a straightforward puzzle that required working out valid passwords. The theme seems to be that part 1 is relatively easy and sets you up conceptually for part 2, which is more difficult. The difficulty somewhat depends on how general your solution is to part 1.
Day 3: Toboggan Trajectory
Here, we’re counting the number of trees encountered whilst skiing down a slope.
I’m beginning to see people’s creativity. As if solving the puzzles weren’t enough, some people are creating animations of the puzzles! Here’s a good one.
Day 4: Passport Processing
The puzzles are taking me longer to solve. This is partly because I don’t know Dart very well but also because the puzzles are harder.
Day 5: Binary Boarding
Today, we’re trying to work out where to sit on a plane because we’ve lost our boarding passes.
The person who created these puzzles is creative.
Day 6: Custom Customs
In the story running through the puzzles, we’re a making a Christmas journey in which we encounter obstacles that require us doing fantastic things — like deciphering custom forms!
I realise after solving today’s puzzle that there is simpler, shorter and quicker way of solving it. This happens on some days: I don’t see some pattern in the data.
Day 7: Handy Haversacks
The puzzles are getting more ingenious. We’re placing bags within bags based on elaborate rules about their colours. They make Russian dolls look tame.
I was pleased with my solution, which used regular expressions — an elaborate and precise way of searching for data within other data.
Some days, the puzzle points you (whether you realise or not) towards using a particular computer science algorithm or data structure. It’s nice to short-circuit this sometimes.
Day 8: Handheld Halting
Writing a program to process another program is interesting! We were given some instructions and had to create a program to run this program. It turned out to be straightforward but it’s a good way of learning, at a basic level, how computer programs run.
Day 9: Encoding Error
Sometimes a puzzle seems complicated and turns out to be easy. This will vary from person to person, based on experience. This one was easy.
Day 10: Adapter Array
I built a graph to work out this puzzle. A graph, in computing, lets you structure data in a particular way so that you can "travel" around it working out connections or something else.
Day 11: Seating System
The Seating System was an opportunity to model people arriving and leaving a waiting area. Here’s a colourful animation of what’s going on.
I was happy to complete today’s puzzle because this was when the puzzle was supposed to get difficult according to Leo Laporte.
Day 12: Rain Risk
Occasionally, knowledge in other fields helps. I used my hiking navigational skills to model this puzzle. We were given instructions to navigate a ship. The second part, as happened occasionally, re-interpreted the input data so that we had to adjust our part 1 solution.
Day 13: Shuttle Search
Sometimes, the puzzles include huge numbers. For example, the data type must be changed to store the number. Other times, the solution to part 1 of the day’s puzzle, if used in part 2, would result in a program running for days! Today that was the case.
One way of solving the puzzle was to use the Chinese remainder theorem, which I didn’t know. However, you could also analyse the output and look for patterns in the data, which is what I did. I like it that even if you don’t the theory behind the question, you can generally use logic to work it out.
Day 14: Docking Data
By now, I’m getting quite comfortable using the Dart programming language. My solutions are mainly object oriented but i’m beginning to use more functional constructs, such as map, reduce/fold, and select.
The puzzle involved bitwise operations, which I’ve not used for years.
Day 15: Rambunctious Recitation
The description of this puzzle, a memory game, was longer than the solution! The challenge was to get the program to complete in a reasonable time.
Day 16: Ticket Translation
Every day, there is input data for the puzzle, usually a file you download. The puzzle setter also, helpfully, provides a small amount of data to test your program with. The output of that test data is provided. This lets you develop your solution and test it to ensure you get the correct answer for the test data. It can be dispiriting, as witnessed on the reddit forums, for your solution to work on the test data but not the real data. Luckily, that rarely happened to me.
As the days progressed, I became better at converting the input data into a more structured form for processing.
Day 17: Conway Cubes
The title refers to John Conway, who created a game called Game of Life, in which something evolves according to its initial state.
Programmers come across this one way or the other and usually write their own version. Here’s an animation of today’s puzzle.
This was the only day I split my solution into two files: one for each part. The first part was a 3D puzzle and the second turned it into a 4D puzzle. It was easier to just add an extra dimension to the code in a separate file than to make it work for both 3D and 4D.
Day 18: Operation Order
This was a fun puzzle with a twist. We had to write a calculator to work out various expressions. The twist was that the precedence order was changed for addition and multiplication. The second part fiendishly introduced different rules and required me to re-acquaint myself with reverse polish notation.
Day 19: Monster Messages
Whilst part 1 was straightforward, I didn’t have time to do part 2 on that weekend. I returned to it after day 25.
There were many ways to solve this. I used regular expressions, which I regard as somewhat magical although others hate them. One of the difficulties is to understand what you’ve created after a few days since it’s just a load of symbols!
My solution required dynamically creating a regular expression, which made an already obscure technique even more opaque!
Day 20: Jurassic Jigsaw
On the day, I didn’t have time to do this because I was doing something that weekend. This was the last puzzle I came back to. It was, for me, the most time-consuming to code. It was one of those puzzles that’s easy to understand but not so easy to code. Looking at the reddit forums, others struggled with this.
The puzzle introduced about a hundred tiles that you had to rotate and flip to align their borders. It was a double-sided jigsaw puzzle you had to write a program to solve! Once you’d completed the jigsaw puzzle and removed the borders of each tile, you had to search for sea monsters!
When I did complete the puzzle, I was very happy with it. There is something satisfying about spending many hours on a puzzle and finding your answers are accepted by the Advent of Code website!
Here’s a stunning animation of the puzzle being completed.
Day 21: Allergen Assessment
Searching for allergens can be fun! We had to work out which ingredients couldn’t contain various allergens then list the dangerous ingredients.
Day 22: Crab Combat
I didn’t think I’d be playing space cards with a crab just before Christmas!
There was, for me, more functional constructs on day 21’s solution. Today, having a Game class was a good choice for part 2 because I could easily create as many games as I wanted to without keeping a tab on the state of each game. In part 2, each game could spin off sub-games and sub-sub-games and so on!
Day 23: Crab Cups
One of my goals for 2021 is to learn a pure functional programming language, such as Haskell.
Day 24: Lobby Layout
Today was similar to day 17, which had a game of life. However, this time, we were presented with hexagonal tiles and were flipping them based on some rules.
The end was near! Surely, the last day wouldn’t be difficult!
Day 25: Combo Breaker
The puzzle setter took mercy on us. There was only one part to the final day’s puzzle.
After resting for a few days, I went back and did the one and halve puzzles I’d left.
The Advent of Code was at times intense and frustrating but mostly enjoyable. That is the nature of programming!
The good news is that I can go back and do the puzzles for previous years, 2015 to 2019!