Advent of Code - Polyglot Edition
Two years ago, Eric Wastl announced his Advent of Code: an advent calendar with a different programming challenge every day. During the event, you helped Santa power his snow machine by completing the two tasks for that day.
That year, I intended to learn Python, so I set out to complete all 25×2 challenges in it. The year after, I tried Rust, but found out that it really doesn’t work that well for small, one-off programs. This year, I upped the ante: I would use a different programming language every day. Other people have done this (someone actually did it twice) but I wanted to know whether I could do it. So here is my quick review of the event and the languages I used. I will not go into detail for every day, but will show general trends.
If you don’t feel like reading all of this but would prefer to just see the abominations I’ve made, they’re all in my Advent of Code repository.
Day 1: Should’ve been better prepared
I did’t start out with the idea to do the polyglot challenge, I just got some friends to commpete with me. So, I go for my most trusted tool and code it up in C++. Of course that works, but now I can’t use it again. Oops.
In hindsight, I probably should’ve used a spreadsheet, just for showing off, but now we have started.
Day 3: Don’t be fooled by an easy part 1
Day 3 seemed simple enough. Given a simple definition of a spiral, find the position of a particular number and return the Manhattan distance between that and the center of the spiral.
After solving some off-by-one errors, I found the analytic solution, and since it’s not that hard to convert a formula-like thing to any programming language, I chose Clojure. This went over as well as could be expected.
However, for the second part, there was no analytical solution, and you really had to construct the actual spiral. I have to admit that this got me stuck for a few days. I finally found some help from another solution, which cleverly generated an infinite sequence of steps, which I then could use to walk the spiral and actually compute each value.
Day 10, 11, 16: JVM languages are nice
Wikipedia has a list of JVM languages and most of those I have done during the event. Contrary to Java itself, most of these languages shine in their brevity and expressiveness.
I first tried Kotlin since I work with IntelliJ a lot, and generally like the stuff that Jetbrains makes. Implementing a hash function is a pain in any language, but Kotlin made it somewhat nice. Ranges are always nice, but I was a bit frustrated that it includes the upper bound. The succinct lambda syntax was a nice extra, and I really liked the concept of explicitly nullable values.
A main downside of Kotlin, was that it was not actually a scripting language, but you still had to compile it to a jar file to run it. Scala fixes this, as you can compile and run it simultaneously like a script with a regular shebang line. Pattern matching was useful for day 11, because I could easily parse the grid directions that way. No other fancy functional language features had a change to shine, however.
To finish up the group, there’s Groovy. At first, I didn’t want to use it since it is so similar to Java itself. When I couldn’t think of another language on day 16, I decided to do it anyway. The result is a script-like version of Java. It’s not bad, but it’s not good either.
Day 15: Functional programming in Haskell
Having learned from my previous mistake, I chose Haskell for a day for which I expected the second part to be somewhat similar to the first. Haskell’s lazy evaluation makes it great for generating infinite streams, which made it easy to implement the streams.
Implementing the second part is quite easy then as well, since you can just apply a filtering operation to the resulting stream. I do regret that I couldn’t get command line input to work, so the two starting points are hardcoded.
Pro tip: actually compile your Haskell! Running it with runhaskell
is
a lot slower.
Day 6, 20: Programming for non-programmmers
I an probably not the target audience for neither Matlab nor R, but
they’re both still usable languages so I figured I’d use them anyway.
They both are somewhat flawed when reading from the standard input.
Matlab has the input
method which prefers to read valid Matlab, but
can be made to just read a string, which you can later get numbers out
with scanf
.
R cannot read formatted data if its life depended on it, I first read it as a string, perform some cleanup on it with regex, then open that string as a file and read tabulated data from it. This wasn’t my idea either, this came from a StackOverflow answer.
Other than that, both languages are quite performant if you don’t mind not having any data structures and if you can avoid for loops. The former you can work around (matrices are almost sets of vectors, right?) and the latter you can solve by making everything an aggregate operation.
I feel like I should include Lua in this list, but other than starting its arrays at 1 it has done me no harm.
General opinion on the event
It was way harder than I expected to find 25 languages to program in. That being said, there are some that I tried but did not succeed in:
- I couldn’t get Objective C and its runtime to work on my laptop, even though people insist that it should work on Linux.
- Erlang (and related languages) is a pain to wrap your head around
- There are people who do all of this in specialized languages like J. I admire those who can. I tried. I cannot.
That said, you can see lots of differences in the expressiveness of the languages I used. The specialized math languages are really expressive for their length. On the other end of the spectrum, we have the usual suspects of C# and Java, with Rust added in. To be fair to Rust, the day I used it was a very code heavy day.
When you look at the lines of code needed for each day, you see a small trend of code getting longer as the event continues, but this effect is way weaker than I expected it to be, and is largely obscured by days where the code was just a lot longer in general.
I liked it. Contrary to previous years, there wasn’t so much as an uphill battle writing more code every day. I did miss the more challenging exercises from previous year. I felt that there was not really any day on which you had to try very hard to get an efficient solution. Brute force pretty much always worked.
That being said, this year was lovely once again. I really enjoyed the backstory, even though I kind of forgot that I was fixing a printer at the end. Eric Wastl, you did a great job. See you next year.