highlights
Dec 20, 2022

The Unison Advent-of-Code mega writeup

Rebecca Mark

We've been blown away by the creativity and ingenuity of the Advent of Code 2022 solutions that have been shared by members of the community. In a surprising and unprompted gesture of generosity, many community members have taken the time toannotate their solutionswith README's describing their thought processes and algorithms. We love seeing the community come together to share their work and learn from each other.

Advent of Code has brought a lot of new faces to the Unison community. Welcome! We're happy you're here! It has also brought a lot of freshbaselibrary functions and data type libraries into being. We're grateful for the contributions of the community in helping us to fill in the gaps.

In celebration of the season, we've collected a smattering of of our favorite solutions. Here's to you! đŸ„‚

The remainder of this post contains spoilers for the Advent of Code 2022 puzzles. We've tried to highlight unique solutions and illuminating writeups. Often, we present multiple approaches to solving the puzzles from the community so you can see the diverse and brilliant (and at times comical) minds at work in Unison. There werea lotto choose from so the selection here is somewhat arbitrary. The links and notes are hidden behind a folded doc, so you can choose whether to peek or not if you intend to catch up.

Day 1: Calorie Counting with Stew O'Connor 🔱

Day 1: Calorie Counting with Stew O'Connor 🔱

If you thoughtDay 1was gonna be quick, you should know, we can turn most exercises into a chance to yak-shave.

We loveStew O'Connor's solution to Day 1because he used the input parsing step as an opportunity to improve theUniparsec library.As a result of this puzzle, the Uniparsec library can parse input directly into aMonoiddata type. Theadvent of code day 1 READMEexplains these changes in detail.

Day 2: Rock Paper Scissors with Rebecca Mark 📃

Day 2: Rock Paper Scissors with Rebecca Mark 📃

Advent of CodeDay 2is a game of Rock Paper Scissors with a twist. The twist is that the rules of the game are encoded in a text file and you're given varying strategy guides to determine your response.

Often, half of challenge of Advent of Code is parsing the input. This month offered a timely opportunity to updatethis abilities based parser libraryhosted on Unison Share. With this parser, we can do things like parse a line of input directly into datatypes that model the game play for easy scoring. That's whatthis solution,written by yours truly does for parts 1 and 2.

Day 3: Rucksack Reorganization with Chris Penner and company 🎒

Day 3: Rucksack Reorganization with Chris Penner and company 🎒

Day 3we did as part of community coding livestream with Unison team memberChris Penner!We had a lot of fun solving this one together! You can watch the recording below.

Day 4: Camp Cleanup with Calvin Sauer 🏕

Day 4: Camp Cleanup with Calvin Sauer 🏕

We love this solution toDay 4byCalvin Sauer.It's a wonderful example of how to use the newly addedNatSet data typeto solve the problem of identifying whether a range of values fully contains another. A NatSet is a Set which is optimized for containingNatelements, so you might reach for this datatype instead of the genericSetnext time your code requires storingNatelements or things that can be encoded asNatelements.

Day 5: Crates with Jemma Nelson 📩

Day 5: Crates with Jemma Nelson 📩

Advent of CodeDay 5is a puzzle about moving groups of crates around using cranes.

This solution and documentation byJemma Nelsonis one of our favorites. Highlights include finding and using thetransposefunction for rotating the crates and a handy recursive function for moving the crates around. We love that others can follow along usingthe writeup,or shall we say, we are very... crateful for it! 🎁

(I'm sorry, I will see myself out.)

Day 6: Tuning Trouble with Calvin Sauer and RĂșnar Bjarnason đŸ€ł

Day 6: Tuning Trouble with Calvin Sauer and RĂșnar Bjarnason đŸ€ł

Day 6's Advent of Codepuzzle involved finding characters in an input string that did not repeat in a given window.

RĂșnar's solution used theStreamability to inspect the input, also prompting some new functions in the standard library.His day 6 READMEgoes into depth to explain the new window function.

For a creative optimized O(n) solution,Calvin Sauer's solutionwalks the character input with adata.Map,incrementing and decrementing a count of characters until a duplicate is found.

Day 7: No Space Left with RĂșnar Bjarnason and Stew O'Connor 🗄

Day 7: No Space Left with RĂșnar Bjarnason and Stew O'Connor 🗄

ForDay 7's puzzlesWe needed to model a file system, with information about files, sub-directories, and file sizes provided by a log of commands as our textual input.

This solution by RĂșnar Bjarnasonuses a Zipper to traverse the directory tree structure as its being parsed! Zippers are data structures that consist of a focus and some surrounding context. The focus is the current node in the tree, and the context is the rest of the tree. With a zipper over the directory tree, you can do things like move up and down the file system, add information as it's revealed, and keep track of what directory nodes you've visited. Check outRĂșnar's day 7 READMEfor more about theTreeZipperdata type he used.

As a result of this puzzle, we even have a new data structure library for you all to enjoy:Rose Trees and Zippers.đŸŒč

If zippers aren't your thing.Stew's solutionuses adata.Mapas the data backing for the directory tree structure. After the input is parsed, thedata.Mapis updated with new information about the file system. If you're ever curious about thePatternAPI for parsing text, this README contains a fantastic example.

Day 8: Treetop Tree House with Cody Allen đŸŒČ

Day 8: Treetop Tree House with Cody Allen đŸŒČ

Day 8gave us the hights of a forest of trees in a grid. We needed to identify which trees in the forest were visible from north south east and west given their height.

Cody's ingenious solution to Day 8 featuresagloriouswriteup.Chief among the innovations here is that rather than writing separate functions to identify visible trees in each direction, Codyrotated the whole forest 90 degrees.Herculean! 🏆

Day 9: Rope physics with Saif, RĂșnar, Cody, Calvin, Jan, and Joe đŸȘą

Day 9: Rope physics with Saif, RĂșnar, Cody, Calvin, Jan, and Joe đŸȘą

A number of folks came up with similar solutions toDay 9's puzzlesby writing functions that move the head of the rope one step and subsequently update the tail, you can readRĂșnar's solution writeup,Cody's solution writeup,Saif's solution writeup,Jan's solution writeupandJoe's solution writeupfor their generous explanations. For a slight variation,Calvin's solution to the rope physics puzzlesimplifies the calculation of the location of the rope by parsing the input as a delta representing the direction of the rope's movement.

😆 This puzzle inspired some real gems:

  • "Assume a spherical rope in an ideal vacuum" - Joe Harrison
  • "I'm revising history and writing this as though I used Int from the beginning" - Cody Allen
  • "The only difference with part 2 is that we need to calculate the tail of the tail of the tail... ten times" - Saif Elokour
  • "Rope physics. Yay." - Calvin Sauer

Day 10: Cathode-ray tube featuring Joe Harrison and Calvin Sauer đŸ“ș

Day 10: Cathode-ray tube featuring Joe Harrison and Calvin Sauer đŸ“ș

🐣 What's a cathode ray tube? Just kidding, Unison is a young language but we remember the cathode ray tube'sfamiliar buzz.

This puzzleinvolved calculating the value of a signal at specific intervals in a sequence of clock "ticks" or cycles.

BothThis solution by Joe Harrisonandthis solution by Calvin Sauerare great examples of understanding the constraints of the domain being modeled and simplifying it to make subsequent computations more straightforward. Check them out, they are very clever!

Day 11: Monkey in the Middle with ChatGPT đŸ”

Day 11: Monkey in the Middle with ChatGPT đŸ”

What were these monkeys doing?Day 11'sinstructions werewild.

The real galaxy-brained problem solving innovation from the Unison community is that RĂșnar fed the instructions into ChatGPT. đŸ€– The puzzles forDay 11became much more intelligible afterwards.

Here's what part 1 of the problem is in plain English:

"Four lists are given, each with a set of starting items and an operation that changes the item’s value. After the operation is applied, the item is tested based on a specified value. If the test is true, the item is appended to a specified list. If the test is false, the item is appended to a different specified list. The process repeats until all lists have had an iteration. Each time an item is inspected, its value is divided by three and rounded down before the next operation is applied.

The above process repeats for 20 iterations. After 20 iterations, the total number of items that were processed by each list are tallied. The number of items processed by the two most active lists are multiplied together, and this number is the answer."

Thank you, ChatGPT. 🙏

Day 12: Hill climbing with Dijkstra and company 🌄

Day 12: Hill climbing with Dijkstra and company 🌄

We did not expect anyone to implement graph traversal algorithms for us as a result of Advent of Code! (Or maybe we did, and Advent of Code is a ruse to generate more useful code examples for everyone. đŸ„ž)

Day 12involved finding the shortest path between two points on a hilly terrain.

This set of puzzles inspired a variety of approaches, some of which we've highlighted below.

This solution by Calvin Saueris an implementation of theA* search algorithm.Thanks Calvin! That's sure to come in handy in the future!

Another solution usedBreadth First Searchto solve the problem. You can read a fantastic walk through of the algorithm and solutionhere in Joe Harrison's day 12 README.

Saif Elokour wrotea brain melting hill-climbing approachthat you should check out as well.

And finally, what would Advent of Code be without a solution that usesDijkstra's algorithm?Check out this implementation by RĂșnar Bjarnasonto see what that looks like in Unison.

Day 13: Distress signal with Eduard Nicodei đŸ—Œ

Day 13: Distress signal with Eduard Nicodei đŸ—Œ

We really enjoyedthis solution by Eduard NicodeitoDay 13's puzzlesbecause it truly embodies the spirit of Unison's Advent of Code. To learn more about Unison ability-based parsers, Eduardwrote a whole mini parser combinator librarybased on an existing library in Unison. In addition to explaining the puzzle solutions,the READMEcontains a full explanation of how theParseability works so that others can learn about it. Amazing! đŸ„Č

Day 14: In the Regolith Reservoir with the Unison community ⏳

Day 14: In the Regolith Reservoir with the Unison community ⏳

Day 14 of Advent of Codeinvolved calculating the number of falling sand units in a cave filled with rocky obstacles.

A number of solutions modeled the cave with aMap (Nat, Nat) Celldata structure where theCellwas either aRock,Sand,orEmpty.Check outthis amazing writeupfor a map-backed implementation by Unison community memberEduardwho also wrote a custom "cave viewer" function.

We also live-coded this one together in a Community day stream.

A notably different implementation wasRĂșnar's cave algorithm,which used amutable ByteArray data typeand a runloop to track the units of fallen sand.

This implementation has a number of performance optimizations. First, storage of the "cell" value is made more compact by using a ByteArray rather than a data type likeList awhere it's possible to store any type. Second, usage of a flat array allows for fast random access and array element updates. It might seem non-intuitive to map a 2D grid into a list-like data structure, but to do this you can use an indexing scheme based on the row length and the desired (x,y) coordinates. Your array index from coordinates can be calculated asindex = x * rowLength + y.Very cool, RĂșnar! đŸ€©

Day 15: Advent of Code Day 15: Beacon Exclusion Zone with Joe Harrison

Day 15: Advent of Code Day 15: Beacon Exclusion Zone with Joe Harrison

ForDay 15we were given a grid of beacons and signals and tasked to find the locations where the beacons could not be located for a certain row.

We are in awe of the curiosity and care evident in these explanations of your work. Take a look at Joe Harrison'sday 15 READMEit's replete with diagrams, examples, and links to other resources.

Day 17: Pyroclastic Flow - RĂșnar shares some bitwisdom đŸȘš

Day 17: Pyroclastic Flow - RĂșnar shares some bitwisdom đŸȘš

Day 17's puzzlelooked a bit like Tetris; rocks were stacking on top of one another in a long tunnel whilst being buffeted back and forth by jet streams.

It sounds like RĂșnar worked hard to develophis solutionsolution and offered this hint: "this solution is completely insane, I decided to represent each 8x8 block of the tunnel as a Nat. This was my first mistake"

Duly noted, RĂșnar.

Day 18: Boiling Boulders with Joe Harrison 🌋

Day 18: Boiling Boulders with Joe Harrison 🌋

ForDay 18,we needed to calculate the surface area of lava cubes in a 3D grid given x, y, and z coordinates. If, like me, you think imagining lava voids in three dimensional space is a little mind melting, you might findthis solution and thorough write-up by Unison community member Joe Harrisonespecially refreshing.

This solution collects the coordinates of the lava cubes in aSetand then finds theirVon Neumann neighborhoodalong the three axes. We won't spoil everything here,This solution writeup is đŸ€Œ. Really, you should read it,but suffice to say we're impressed with the elegance of this solution.