Here's my go at solving the puzzles from https://adventofcode.com/2022 - with the extra challenge of using a different programming language for each day.
All the icons below are clickable links to my solutions and some notes/thoughts on the language used that day. Most of the notes were written well after-the-fact so, for better or worse, probably aren't as brilliant as they could be at capturing my emotional "at the moment" opinions.
Day | Language | Part 1 | Part 2 | Notes |
---|---|---|---|---|
1 | Python | ✅ | ✅ | 🗒️ |
2 | Lua | ✅ | ✅ | 🗒️ |
3 | Odin | ✅ | ✅ | 🗒️ |
4 | D | ✅ | ✅ | 🗒️ |
5 | Perl | ✅ | ✅ | 🗒️ |
6 | Nim | ✅ | ✅ | 🗒️ |
7 | Awk | ✅ | ✅ | 🗒️ |
8 | NodeJS | ✅ | ✅ | |
9 | Bash | ✅ | ✅ | |
10 | Ruby | ✅ | ✅ | |
11 | Dart | ✅ | ✅ | |
12 | Zig | ✅ | ✅ | |
13 | Go | ✅ | ✅ | |
14 | PHP | ✅ | ✅ | |
15 | Julia | ✅ | ✅ | |
16 | Groovy | ✅ | ✅ | |
17 | C# | ✅ | ✅ | 🗒️ |
18 | R | ✅ | ✅ | 🗒️ |
19 | V | ✅ | ✅ | 🗒️ |
20 | Tcl | ✅ | ✅ | 🗒️ |
21 | Scala | ✅ | ✅ | |
22 | Kotlin | ✅ | ||
23 | C++ | ✅ | ✅ | 🗒️ |
24 | Rust | ✅ | ✅ | 🗒️ |
25 | Haskell | ✅ | 🗒️ |
As a general comment, it is incredible how much "how-to" programming information is available online. I only had professional experience using a handful of these languages, and zero experience with well over half of them. I'm pretty sure my browsing history is now full of "how do I read a file line-by-line in ________" tutorials for all these languages.
Python is such an incredible all-purpose language for programming. It provides so much functionality out of the box and makes it so easy to whip something together. This is the programming language I used for all my solutions in previous years.
This was an easy choice. The problem was trivially solved using look-up tables and, to quote their own docs, "Tables are the main (in fact, the only) data structuring mechanism in Lua".
I'd been curious about Odin ever since I heard EmberGen was written in it. Being very C++-like, it was easy to pick up and work with, and I was pleasantly surprised how much useful documentation I could find. Relevant for this day's puzzle, I particularly liked how switch
statements could accept ranges for a case
(see my solution for the first part as an example). I also felt the brevity in code required for casting between types is a good design decision.
Not much to say. Another C++-like language, easy to work with and solve the day's puzzle. I don't think I took particular advantage of much from the language, other than easily reading a file line-by-line in a for
loop, and splitting strings into arrays.
This brought back memories of trying to dissect/understand and extend Perl scripts at a previous company. The language was a good fit for the day's puzzle, with the built-in support for regex and text manipulation/wrangling.
It's arguably not a big thing, but it annoyed me that I couldn't name my source files 06a.nim
because the filename is used to drive the module name and 06a
isn't a valid identifier. None of the other languages I used had this restriction (at most I'd need to specify a module name inside the source file - D for example). Ignoring that, the language was easy to work with. I like the numeric ranges for for
loops, and the multi-line blocks for let
and var
. The solutions were too short to get a real sense of the language, but I felt more like I was programming in Python than in C++ here - and, especially in this context, I mean that in a very positive way.
I'd never used Awk beyond some simple one-liners to extract a bit of data from some text. I'm really glad I chose to use this language for a puzzle, and this day's puzzle was a good fit with its requirement for text processing (specifically processing a file line-by-line, then ending by aggregating the processed data). I didn't know if Awk would have the support I'd need (associative arrays, for example), and it's been a great discovery to understand just how powerful this language is. I expect I'll be reaching for it in a professional capacity in future.
Working with C# came quite naturally given my familiarity with C++. I liked the support for multidimensional arrays as first-class primitives, and there's some handy stuff in the .NET framework (such as File.ReadAllText()
and Dictionary<K,V>.TryGetValue()
).
This was a tough one for me, with zero experience using R. I really struggled with my ignorance of R vectors vs lists vs matrices vs data frames, but was pretty satisfied with my approach for the first half of the day's puzzle. It felt like R was a great fit for this challenge, allowing a really concise solution leveraging R's data processing capabilities. The second half proved a further struggle, however. I knew the approach I wanted to take, but the implementation left me feeling like I was no longer taking advantage of R and was doing a fairly literal translation of the solution as I'd implement it in Python (or similar).
This was the day's puzzles that I started last (though I still finished these before 22b), so I was running low on languages to choose from. I don't remember how I found V, but it made some bold performance promises, and the syntax looked close enough to C/C++ to be easily approachable. On the whole I actually found it pretty good, with some interesting language design and excellent docs (https://github.com/vlang/v/blob/master/doc/docs.md). One life-saver for this day's puzzles was the built-in profiler, which revealed that my never-finishing code was spending pretty much all its time appending to a datatypes.Queue
that only tracked a head
pointer and thus had O(n)
cost for push
. After making a local modified copy of the underlying LinkedList
struct to also track tail
and give O(1)
for push
, the hotspot in the profile vanished and my code ran in a few seconds.
I chose this language more because I was running out of languages than because I thought it'd be a good fit. To be fair, it was pretty easy to express my solution using Tcl, though it did mean living the programming-interview joke(?) about implementing linked-list functionality.
This has been my main professional day-to-day programming language for the last decade or two, so I was pretty confident that whichever puzzle I ended up using it for would be solved without too much fighting-against-the-language pain. The std
containers were very helpful (I didn't expect to use all of set
, map
and array
, but they each served a useful purpose), and I was able to proceed confidently.
I keep wanting to learn Rust properly, but it never fully clicks with me. Perhaps I'm just too set in my C++ ways, but I keep finding Rust just a bit awkward to work with. Luckily this puzzle didn't require any of the borrow-checking "fun" Rust has to offer, but I still found myself stumbling against the compiler more often than I'd like. The strictness over types (i32
vs usize
for example), regardless how well motivated for safety, was annoying - and I prefer the C-style casting syntax of other languages (i32(x + y)
vs (x + y) as i32
). Maybe I'll still love Rust in the future one day, but not today.
I knew I wanted to use Haskell somewhere in this set of puzzles. This puzzle seemed a good fit as the input data was simple (i.e., no complicated parsing), and the solution I imagined was easily expressed as a combination of mappings and reductions (or "foldings" in Haskell-speak?) ... and because I had pretty much no experience with purely-functional programming languages. Despite the simplicity of the solution, I still spent ages on Google trying to figure out Haskell's specific keywords/methods, and in particular trying to figure out how on earth to actually work with file data in main
. Reading a file via readFile
and splitting the data into lines via lines
was found easily-enough, but I just could not for the life of me figure out how to actually worth with the data. While I wanted to operate on [Strings]
, invariably IO
kept showing up in my error messages. By moving all the logic out of main
and into functions, somehow it just magically worked. I still don't really know how/why - I'm not sure if I want to know how/why - but I'm still frustrated by the hours lost to searching Google in vain.