Advent Of Code is a series of 25 2-part puzzles that must be solved programmatically. The answer of all puzzles is always an integer value.
I’ll try to make a small visualization for each exercise, so I’ll use PICO-8 (Lua) or TIC-80 (TypeScript), since both engines make it possible to quickly draw something with just a few more lines.
- Exercise: https://adventofcode.com/2023/day/1
- Solution: https://git.scambier.xyz/scambier/adventofcode2023/src/branch/master/day1.p8
- Language used: PICO8’s Lua 1
This first day was (surprisingly?) quite easy. Looking at posts on Mastodon, it seems that many participants struggled with regexes and edge cases like
twone. Since I don’t have access to regexes with PICO-8, I just checked for substrings 🤷♂️
And since PICO-8 can’t easily handle big numbers (signed integers can’t go over
2^15-1), I found a function that adds strings.
I wasn’t really inspired for this 1st day visualization, so I lazily printed out the values as the algo was processing them.
- Exercise: https://adventofcode.com/2023/day/2
- Solution: https://git.scambier.xyz/scambier/adventofcode2023/src/branch/master/day2.p8
- Language used: PICO8’s Lua
I had to cheat a bit today. Since PICO-8’s Lua is so limited in features, splitting and parsing strings can get tedious very fast; so I “manually” cleaned some spaces from the input, to make it easier to split lines.
The problem was overall simpler than yesterday’s, just a bunch of
ifs and additions. Almost half of my code is dedicated to the falling snowflakes. This is a classic animation: snowflakes fall 1pixel/second, I used a
sin() function to make them sway left and right. They stop falling once they reach the bottom of the screen, or if there’s already a snowflake right beneath them. Each snowflake corresponds to a red/green/blue cube from the input.
- Exercise: https://adventofcode.com/2023/day/3
- Solution: https://git.scambier.xyz/scambier/adventofcode2023/src/branch/master/day3/main.ts
- Language used: TypeScript
This one was hard.
Not that the problem is particularly hard — finding adjacent items on a 2D grid isn’t really complicated — but I had a bug in my first Lua script, and I absolutely could not find it. The example input was correct, the logs were correct, the different test cases were correct, and yet the end result was incorrect. I trashed the code and tried a different algorithm in TypeScript, which worked. I still don’t know what was wrong in my first draft 😑 I can only guess it was some edge case that I overlooked…
Anyway, once the 1st part was finally done, the second part went smoothly.
I also wrote a small animation that fit the “gears” theme ⚙️ I take 1 out of 10 so-called gears from part 2, report their position on the TIC-80 space, print a
* surrounded by the corresponding numbers, and make those numbers rotate around the cog.
- Exercise: https://adventofcode.com/2023/day/4
- Solution: https://git.scambier.xyz/scambier/adventofcode2023/src/branch/master/day4.p8
- Language used: PICO-8’s Lua
I had to cheat again by pre-cleaning the input. I’m ok with this as it’s kinda necessary with PICO-8 if you want to spend more time solving the problem than cleaning the input.
Anyway, today was quick and easy, perfect for a Monday. I had to read the second part a few times to make sure I understood it correctly. No wonder those elves have issues with that many scratch cards. Gambling addicts.
I was not really inspired for the visualization, as PICO-8 is difficult to work with big numbers. I mean, I do have ideas, but they’re kinda hard to combine with the input/output numbers from the exercises without spending hours on the execution.
- Exercise: https://adventofcode.com/2023/day/5
- Solution: Raw Typescript | TIC-80
- Language used: TypeScript
I was definitely not going to try PICO-8 for this one. With numbers and loops going into the billions, I would have to find an incredibly efficient way to make it work with PICO-8’s neutered CPU. Back to TypeScript.
Reading about this problem on Mastodon, it looks like a many people had run times of hours to find the solution to Part 2. It personally took me 4-5 minutes, so not bad (compared to others), but it could probably be improved.
My solution is not super elegant, but it is readable:
- Parse all map inputs and save them as arrays of tuples in aptly-named variables (
fertilizerToWater, etc.) (code)
- The tuples are
[destination source range], literally as described in the input
- The tuples are
- Write a function that takes a source value, an array of tuples, and returns the destination (code)
- Sequentially call the function for all steps, feeding the resulting destination as the source for the next step (code)
- Log the smallest final destination
For the visualization, I used the example input to illustrate the value transformations from “seed” to “location”.
1: This a subset-slash-custom version of Lua, with most of the standard lib removed.