Day 1: Chronal Calibration
Today, we had to calibrate some weird device that helps fix some weird anomalies. Typical AoC storyline. Now, how do we do that? Well, we need to work with frequencies, in a way that reminded me of frequency hopping. Essentially, our frequency starts at 0, and every line in our input gets added to or subtracted from the current frequency. So far so simple, you could do it on paper, right?
No, you could not, your input will be far to long...
Part 1 is fairly straightforward; the challenge is to just find the final frequency. I started out by splitting our input on newlines, which just gave me a list of numbers with signs like this: ["+1", "-1", "+8"] (but much longer obviously). Then all I had to do is to pipe it through a custom (and as I learned, totally unnecessary) function that converted the strings to integers using Enum.map/2, after which I could just fold right to add the numbers up, giving me the final answer. Hooray! Doing this part took me about 10 minutes, half of which was googling how to drop the second element of a tuple.
Part 2 requires to you infinitely iterate over your input until you find a duplicate frequency. That would be your puzzle answer. I had quite a few problems here, so let's break them all down for you.
How do I infinitely iterate?
Iterating in elixir normally is done by using a recursive function (I think). So that is what I tried to do, but obviously I could not do that for infinite iterations. This was probably the easiest problem to overcome with Part 2, all I had to do was pop an element from the beginning of the list using pattern matching ([head | tail] = input) and to then stitch it back together in the end using tail ++ [head]. Well, just a small problem with that: it's inefficient as fuck.
Whenever you add an element to the beginning of a list, you only create a new element. If you now add it to the end of the list, you force the erlang vm to copy the ENTIRE list. And that takes time. A lot of time. Where running Part 1 took less then a second, Part 2 took almost a minute to run. Damn.
Afterwards Luna told me I could just match for an empty list in an earlier function clause and call the main function again with the original list, but I stand by my choice. Not like it's going to run away :D
How do I check if an element is a duplicate?
Let's end this post with a simple question: duplicate checking. I was struggling to find a way to do this, until I thought of accumulators. My solution function takes an accumulator list containing all the frequencies, and part of the tail-recursive function is to check if that list contains the current frequency. Easy. When you know how to do it ;D
So how was it?
I noticed that I definitely improved my brainz skillz a lot. I was able to work out an algorithm in a relatively unfamiliar language in a short amount of time, with only a few struggles. Thanks for reading, and I'll probably reflect on todays leaderboard tomorrow.