Advent of Code 2023 notes
| Problem statements | Source code
2023 was supposedly my third year doing AoC, but I actually did it retrospectively in 2025. I was just appointed leader of CourseTable and I was grinding on it every day. When I chose a language for 2023 in retrospect, I actually had several candidates. First, I started learning Rust in early 2022, but I already happened to do 2025 with it; second, I learned Racket in late 2022 because my friends were all taking an intro CS class, but I don't consider myself proficient enough (I might still revisit it in a future year); third, I learned R in early 2023 in a data analysis an exploration class. Since then, in late 2023, I took another probability class where I was intimidated by assignments using R, so overall it seemed like a year of R. If not now, when?
R was the most awkward language I've ever touched. You can call it powerful and expressive et cetera, but for writing plain old algorithms, it's just a hot mess. Here are the things I've complained about this year:
- No built-in hash maps or sets. String keys into lists are secretly linear under the hood. Even when you use hacks like
new.env()you still have to serialize complex keys into strings. - Terrible typing, which is to say none. Meanwhile all the variable types are crazy complex with vectorization,
sapply/lapplyand stuff. I have to constantly paste into ChatGPT "what's the type of this variable and how do I index into it". - No Int64, like at all?? I had to load gmp to use int64 (of which there were a lot that year!).
- 1-indexing. This is not a problem in itself but it makes translating algorithms a bit harder, especially ones where the list indices are intended as keys rather than arbitrary positions.
- Secret CoW. Hidden performance costs and subtle bugs everywhere. I always have to deep-modify like
a[[i]][[j]][k] <- foowithout saving any intermediate variables. - And of course, performance was slow in general.
- Compared to all of the above, problems like "no priority queues" and "no queues" seem such trivial problems especially since they are solved by the collections package.
On the upside, igraph was very helpful for graph problems like 20, 23, and 25, and I did benefit from vectorization and data frame operations in many problems.
I enjoyed the "theme" this year, since I can clearly see the path we moved through: the different islands, up and down. I don't know if it's a "when you have a hammer" situation, but I find more math problems this year than average, as pure as 9. There were even two problems involving the shoelace formula! Also more graphs and mazes than DP—which I appreciate because again it's not easy to memoize in R.
Difficulty-wise, I think the difficulty is yet higher than 2022. Language problems aside, 5 actually gave me a hard time because I had to wrap my head around how the mappings compose. 8 was tricky as well, especially because it isn't obvious that the naïve solution should work and it's so apparently wrong in most cases. Then it went pretty smoothly until 20 where I spent a lot of time doing it generically before seeing that the circuit has structure. 21 is I'd consider the hardest problem of the year, and again the input is specially constructed so it's unnecessary to write a fully generic solution. 23 is also theoretically sophisticated. It's possible to get away with naïve DFS, but I spent a good amount of time optimizing it, particularly because R is so slow already. These monsters make 24 and 25 look like babies (especially when I can cheat with igraph for 25)!
