Module advent_of_code_2021::day_7 [−][src]
Expand description
This is my solution for Advent of Code - Day 7 - The Treachery of Whales
Today’s input was a bunch of 🦀 crabs 🦀 (in submarines ) who can only move sideways (despite being in submarines 🤷.) The challenge was to find the most efficient position to align them to, given a particular cost function for a crab submarine to move a certain distance.
For part one this was a linear cost, which reduces to finding the median, and calculating the
cost for each crab to move to that median. This is implemented by find_distance_to_median.
As an informal proof for this method consider: for any given position value, incrementing that
position by one increases the overall cost by one per crab below that value, and decreases it by
one per crab above that value. Decrementing the position has the opposite effect. For any crab
other than the median, if you move the value towards the median, more crabs are on the side that
decreases the cost (by definition), and so the overall cost decreases. An interesting note in
the case of an even number of crabs, the value of either crab in the middle pair, and any values
between them will produce the same optimal cost, so in that case we can just pick one
arbitrarily.
For part two the cost function was the triangular number of the distance, 1 => 1, 2 => 3,
3 => 6, … or (n * (n+1) ) / 2. This is implemented by find_triangular_distance_to_mean.
I have to admit I guessed the mean here. It seems reasonable - if the cost increases as you move
further you want a lot of crabs to move the shortest distance they can. Given there was an issue
where the rounding was slightly off (rounding the calculated mean worked for the sample, but
floor was needed for the puzzle input) I suspect the mean is the limit as the steepness of the
cost function increases, and it’s close enough (±1) for triangular distance. But equally that
may just be a weirdness of integer maths. If anyone has information on more concrete theory
about this I’d be interested in a link.
Functions
First find the median by sorting the list and taking the value at the midpoint. As discussed in the summary, either midpoint is fine in the case of an even length list, so just use the default rounding. Secondly iterate through the list to total the distance to the median and sum those values.
Very similar to find_distance_to_median with three differences:
The entry point for running the solutions with the ‘real’ puzzle input.
