Advent of Code 2020 retrospective

advent of code aoc2020 haskell

It’s over.

What a year! Between Covid-19, family matters, work matters, the new site and all, not much of that Advent of Code went smoothly. I did manage to solve all the puzzles in time.

This year’s personal challenge was to write about it. So I kept using Haskell—why change if it works so well—and upgraded the programs to full-fledged posts.

Literate Haskell is really nice to use. The language’s disregard for order of definitions makes TANGLE mostly redundant, which adds to the cohesiveness. With the notable hitch that imports still have to be on top, so there’s always that skippable heading block.

Not all puzzles were as post-worthy as the other. I tried to strike a balance across a broad spectrum of styles: some posts are straightforward commented implementations, other feel more like written live cuts, others go through more reflection of how puzzle and solution match…

This year was a rather easy one. On the math and computer science fronts, there wasn’t much left for me to discover. On the Haskell front, I took the opportunity to explore alleys I don’t take everyday. Most notably this year:

I’m slowly moving to Relude for personal projects and did so too for Advent of Code. It didn’t last half a day. AoC is really more of a “solve it once” mindset. I really can’t get myself to give a damn about handling user error properly when there’s only one input, error-free by definition.

I’m not including benchmarking of any kind. Same reasoning, most of this code is optimized for clarity of explanation, and that often means using the native default list structures. Unambiguously suboptimal, demonstratably adequate in face of the small input sizes. It’d all be dwarfed by the lens monstrosity anyway.

Here’s the full list of posts and summary keywords; the files are cloneable from github.

Literate Haskell post Notes
Day  1 — Report Repair brute-force implementation
Day  2 — Password Philosophy naive implementation, Parsec parsing
Day  3 — Toboggan Trajectory naive implementation
Day  4 — Passport Processing naive implementation, HOF
Day  5 — Binary Boarding math-inspired implementation
Day  6 — Custom Customs naive List-based implementation
Day  7 — Handy Haversacks inefficient tree-based implementation on top of recursion-schemes
Day  8 — Handheld Halting open-out design, may contain trace amount of monads
Day  9 — Encoding Error zippers and scans
Day 10 — Adapter Array referential transparency, dynamic programming, folds
Day 11 — Seating System ST reference mesh
Day 12 — Rain Risk complex-based rotations
Day 13 — Shuttle Search chinese remainders, extended Euclid
Day 14 — Docking Data ridiculous yet satisfying lens-based implementation
Day 15 — Rambunctious Recitation top-down design, monad transformers
Day 16 — Ticket Translation naive implementation
Day 17 — Conway Cubes dimension-agnostic linear algebra, a few lenses
Day 18 — Operation Order parsing with Parsec
Day 19 — Monster Messages algebra, regular expressions, Parsec and ReadP parsing
Day 20 — Jurassic Jigsaw reconstruction with the list monad
Day 21 — Allergen Assessment Set operations, simple Parsec parsing
Day 22 — Crab Combat HOF, recursion
Day 23 — Crab Cups evolutive design, mutable linked lists in the ST monad
Day 24 — Lobby Layout naive implementation, code re-use
Day 25 — Combo Breaker brute-force modular arithmetic

Bonus it’s not Haskell, but it’s literate: solving day 7 with a git commit graph.

And that pretty much wraps up the year.

Thanks again Eric Wastl for crafting puzzles of such quality year after year. I know the work that goes into making them so unnoticeably good, and doing so consistently by piles of 50 is superhuman.

I can’t wait ’til next year!