AoC 2021 and thoughts on Odin
Date written: 2021.12.29
I first heard about Advent of Code (AoC) a couple of years ago, but this year was the first time I put serious effort into it. For those unfamiliar, AoC is a series of programming challenges which run from December 1 to December 25 each year.
The first couple of challenges are trivial, but by the middle of the month the problems usually reach a complexity where competent programming is required. For example, the first AoC problem this year was to calculate the number of times an integer is greater than the integer before it in a long list of integers, whereas in the middle of the month the task was to calculate the path of least-resistance through a 100x100 grid of single-digit numbers representing resistance. Loads of people start an AoC, but hardly anyone finishes. Whereas over 200,000 people solved part 1 of the first problem this year, less than 15,000 solved part 1 of the final problem.
From what I gather there tends to be three main reasons why people do AoC:
- The excitement of competing with other people to get solutions ASAP using python.
- Using the problems as a guide to learn a new programming language.
- Using the problems to practice an existing programming language.
I was squarely in the dot point 3 camp the first week, practicing vanilla C. After taking the core hardware / computer architecture course at Cornell (the infamous CS 3410), for the first time in my life I actually understood how C worked, so wanted to practice C by writing code from scratch.
Writing code in C is generally very nice. For one, the translation from C into unoptimized assembly is usually simple, so you can pretty much program the way you want the instructions executed on hardware. This is the opposite of interpreted languages, and languages with garbage collectors, which I generally hate.
There are a couple of downsides of C though: simple things such as looping from 0 to 100 requires more syntax than should be needed; switches need to have constant statements; there is no easy way (to my knowledge) way to issue compile-time arguments to adjust constants.
Luckily, on day 8 I heard of a solution to these issues. I was listening to a podcast hosted by Abner Coimbre about C and C++ replacements. Two of the speakers had created their own programming languages, and one of them had created a language which had four principals: simplicity, high performance, joy of programming, and modern systems. The speaker was Ginger Bill, and their language was Odin.
I begun reading through the documentation. Although there wasn't much of it, I loved what I saw. Within two days I had solved Pt 1 of the Day 8 problem in Odin, and several days later I had solved Pt 2 too. Despite not having even heard of Odin the week before, I was now able to write basic programs in it.
The next few days consisted of reading more of Odin's open source-code library, asking questions on Odin's Discord, and experimenting with the language. Throughout this time I found the small, technical, and concrete goals of the AoC challenges great motivation to continue learning the language.
The AoC reddit also proved to be great motivation too: every day a couple of inside-jokes and memes regarding the latest problems would rise to the top. Seeing the jokes other people were making would only make me want to understand them more. Here are my favourite posts:
By Day 11 of AoC, I was sold on programming in Odin. Programming in Odin feels how programming in C should be. Gone is the ridiculous notion of using * for multiplication, pointer declaration and dereference. Strings are now a data type. If you have nested loops and want to break, you can control with a label exactly which loop to break out of. Functions have several return types. Variable declaration is both easier and more distinct from variable assignment. And the compiler has generally excellent error messages, saving so much debugging time. Odin is now my default programming language.
Overall, the AoC problems themselves were a bit hit and miss. There were some gems this year though. Day 4, Day 11, and Day 15 were particular highlights. (Namely, figuring out which of a series of bingo boards will win first and last; a basic simulation to show how animals which blink can reach equilibrium (as described in this video); the least resistance problem described earlier. Note that while the least resistance problem was standard, in my case it was an excellent demonstration just how terrible Dijikstra's algorithm becomes when graphs have a large number of vertices. Next time I'll be using A* search.
I didn't finish all of the problems, but I finished most of them, by which I mean more than half. My solutions are available in my AoC github repo. Programming solutions in any low-level language obviously takes more time than in an interpreted language, but by doing so you are actually able to take control of how data is stored and manipulated, and as such you can practice making fast programs. No fast program was ever written in python or javascript. (At least, none which were not calling C libraries under the hood!) I reckon if I didn't switch to Odin on Day 8 I would have been able to do all of the AoC problems in C, but I do not regret the choice at all.
I plan to do AoC again next year, hopefully by which time Thekla's in-development language which inspired Odin will be in open beta. I am even more excited about programming in that language than in Odin, at least for now.