Module advent_of_code_2021::day_18 [−][src]
Expand description
This is my solution for Advent of Code - Day 18 - Snailfish
Today was doing convoluted arithmetic on ‘Snailfish Numbers’, which are made up of a binary tree with digits at the
leaves. The representation was easy enough, but I had to box the non-leaf nodes to prevent the compiler
complaining about the type being potentially infinite. I tried just using references, but it made satisfying the
borrow checker very difficult. This resulted in SnailfishNumber and SnailfishNumber::from, a recursive
function that parses a line of the input (each is one number).
The main difficulty of today was implementing SnailfishNumber::add. The actual addition is simple, but the
resulting checks that the invariants on the new SnailfishNumber hold: no pair deeper than level 4, no
leaves that are not single digits, and resolving them if they don’t involved some complex recursion and pointer
manipulation. SnailfishNumber::check_depth handles checking if a pair is too deep, and also if it finds one,
handles passing the numbers of that pair left/right as it unwinds the recursion. SnailfishNumber::check_digits
handles splitting leaves with numbers that are not single digits into the relevant pair.
Finally SnailfishNumber::magnitude implements recursively reducing a SnailfishNumber tree into a single
number for calculating the result. With these in place, add_numbers folds each line of the input into the first
number using SnailfishNumber::add for the solution to part one. max_sum uses Itertools::permutations to
match up each pair of numbers in both orders, map them to the magnitude of the sum, and reduce that to the maximum.
Enums
When a pair is exploding due to being too deep, the number that still needs to be assigned is passed up to the parent. This indicates which way it is travelling / which half of the pair it came from.
Represents a snailfish number as a binary tree
Functions
The solution to part one - fold the list of numbers into the first and return the resulting number. The puzzle solution then converts this to its magnitude, but returning the full tree allows unit tests to compare this to the expectation.
The solution to part two - uses Itertools::permutations to match up each pair of numbers in both orders, map them to the magnitude of the sum, and reduce that to the maximum.
Split the input into lines and parse each with SnailfishNumber::from
The entry point for running the solutions with the ‘real’ puzzle input.
