-
chevron_right
Erlang Solutions: Advent of Code 2023
news.movim.eu / PlanetJabber • 1 December, 2023 • 3 minutes
Hello! I’m Piotr from Erlang Solutions Poland and I have the pleasure of saving Christmas this year with the power of Erlang for you!
This is the second time we participate in the amazing event called the Advent of Code . Last year’s edition was solved by my colleague Aleksander and as far as I know – many of you enjoyed following his efforts. I hope you’ll like my tale of helping Santa too!
I’m going to publish my solutions in my GitHub repository . They will be accompanied by a commentary, added to this page on a daily basis. I will add solutions for each day in an individual folder, with my input file downloaded from the AoC website.
I’m also going to include a bit of microbenchmarking in every solution, with and without JIT. Firstly, to measure the overall performance of the code and secondly to see how much the efficiency improves thanks to JIT. I’m going to measure the computation time only with
`timer:tc/3`
call, as I consider time needed to compile a module and load the input file irrelevant. By “load” I mean: read it and split it into lines. Any further processing of individual lines is considered a computation. I will provide min, max and arithmetic average of 100 runs.
I’ll be implementing solutions as EScripts, so running them is a bit more straightforward. And frankly – I think they are underrated and sometimes I prefer them over writing BASH scripts. I’ll always include
`-mode(compile).`
directive to avoid the interpretation performance penalty. For those who are not aware of this capability, I’ll also run Day 1 without this option to show you how the timings change.
I’m going to run every piece of the code on Linux Mint 21.2 VirtualBox machine with 4 cores and 8GB of memory, hosted on my personal PC with Ryzen 3700X and DDR4 at 3200MHz. I will use OTP 26.1.1.
Day 1
Part 1
I would never suspect that I’ll begin the AoC challenge with being loaded onto a trebuchet. I’d better do the math properly! Or rather – have Erlang do the calibration for me.
FYI: I do have some extra motivation to repair the snow production: my kids have been singing “Do You Want to Build a Snowman?” for a couple of days already and there is still nowhere enough of it where I live.
I considered three approaches to the first part of the puzzle:
- Run a regular expression on each line.
- Filter characters of a line with binary comprehension and then get the first and last digit from the result.
- Iterate over characters of a line and store digits in two accumulators.
I chose the last one, as (1) felt like shooting a mosquito with a M61 Vulcan Cannon. Second one felt kind of less Erlang-ish than the third one. After all, matching binaries and recursive solutions are very natural in this language.
Timings
Min | Avg | Max | |
Compiled + JIT | 0.000091s | 0.000098s | 0.000202s |
Compiled + no JIT | 0.000252s | 0.000268s | 0.000344s |
Interpreted | 0.091494s | 0.094965s | 0.111017s |
Part 2
By choosing the method of matching binaries, I was able to add support for digits as words pretty easily. If there were more mappings than just nine, I’d probably use a map to store all possible conversions and maybe even compile a regular expression from them.
Eventually, the temptation of violating the DRY rule a bit was too strong and I just went for individual function clauses.
And my solution was invalid. Shame on me but I admit I needed a hint from other participants – it turned out that some words can overlap and they have to be treated as individual digits. It wasn’t explicitly specified and ignoring overlaps in the example did not lead to an invalid result – a truly evil decision of AoC maintainers!
Simply put, at first I thought such a code would be enough:
parse(<<"one", Rest/binary>>, First, _Last) -> store(1, Rest, First);
But the actual
Rest
must be defined as
<<_:8, Rest/binary>>.
Timings
Min | Avg | Max | |
Compiled + JIT | 0.000212s | 0.000225s | 0.000324s |
Compiled + no JIT | 0.000648s | 0.000679s | 0.000778s |
Interpreted | 0.207670s | 0.213344s | 0.242223s |
JIT does make a difference, doesn’t it?
The post Advent of Code 2023 appeared first on Erlang Solutions .