Dec 02, 2022

Feeding the reindeer with Unison's Advent of Code tooling ⭐️

Rebecca Mark

This year's Advent of Code is all about feeding the reindeer. Or rather, it should be, but before you tackle the Advent of Code you might have to set up helper functions for doing file I/O, translating bytes into UTF-8 text, and then there's the separate business of downloading your personalized puzzle input and submitting your answer for validation. Those precious nanoseconds add up when you're attempting to make it on the leaderboard! Or maybe you just want to focus on the puzzle at hand. Wouldn't it be nice to run everything in the UCM? Thanks to Unison teammate Cody Allen, Unison has a library to support that.

Unison has set up a template project for the Advent of Code with the goal of getting folks solving puzzles with minimal friction. It takes care of downloading your unique puzzle input, submitting your answer, and will let you know if your submission was correct! You won't have to copy a text blob to a file or input a value into the web form.

Here's how it works

First, pull the advent of code project with the following command:

pull unison.public.advent_of_code .advent_of_code

Next you should log in to the the Advent of Code website to let the Advent of Code know who you are. The Advent of Code client will need to submit your puzzle as you with a session cookie. This involves a bit of browser tooling spelunking so fortunately the marvelous Chris Penner has provided a walk through video for getting the token you need for authentication.

Use that session cookie in one of the ways specified by the project readme and you are set up to download and submit.

In this project, each day is in a namespace which contains two functions corresponding to parts one and two of the challenge.

day01.part1 : '{IO, Exception} ()
day01.part1 = do
  solve input = todo "implement solution for day 1 part 1"
  submitSolution (Day 1) (Part 1) solve

The part you need to implement is the function called "solve". It takes in a value of Text which represents the input, and returns a value of Text which is the value that would otherwise be entered into the Advent of Code website as your answer. Run edit day01.part1 to bring the function into a local scratch file.

When you want to submit your answer you will run something like run day01.part1 in the UCM to see if your answer was correct.

Debugging tips from the team

How do I see the input text before I start my implementation?

You can use the Debug.trace function for quick "printLine" style debugging. This call to Debug.trace will split the input on newlines and take the first 100 lines:

day01.part1 : '{IO, Exception} ()
day01.part1 = do
  solve input =
    Debug.trace "puzzleInput" (Text.split ?\n input |> take 100)
    todo "implement solution for day 1 part 1"
  submitSolution (Day 1) (Part 1) solve

How do I see my answer before I submit to the api?

A fastest way to do this is to redirect the results of the stub function with a call to base.bug. base.bug will abort the program and print the result of solve to the UCM console.

submitSolution (Day 1)(Part 1)(solve >> bug)

I'm in the adventOfCode.dayN namespace, why can't Unison find the standard lib?

Unison namespaces are "scoped" in what they can reference in the codebase so it's common to work with your UCM console at the project "root" ("adventOfCode" in this case). If you've cd-ed into a namespace called adventOfCode.day01 you're one level too far down the namespace tree to reference the lib directory in the project. cd .. to go back up one level and edit the puzzle function from there.


If you haven't joined us in Slack, come by, we're friendly! There's a channel called #adventOfCode, where you can get help with puzzle solving and check out others solutions. A few of the Unison team members have been helpfully documenting their solutions to help others follow along or learn new approaches.

🎄 We hope you're having a very happy Advent of Code!