Notes for Advent of Code 2024
https://github.com/leifmetcalf/aoc-2024/blob/trunk/aoc2024.livemd
Day 2
Problem
You're given a list of reports
7 6 4 2 1
1 2 7 8 9
...
For part 1, find which reports are safe, that is, (strictly) monotone and increase/decrease by at most 3 each step. Then, sum the middle elements of the found reports.
For part 2, you are allowed to remove at most one element from each report to make them safe.
Note
The naive quadratic solution is plenty fast enough for part 2, but there's also a linear solution. If you find an index where a post fails to be safe, then one of the three adjacent indices must be deleted, and it's only a matter of checking the three cases in linear time.
Day 7
Problem
You're given a list of target values and integers:
190: 10 19
3267: 81 40 27
...
Part 1 asks you to find the rows where it is possible to insert left-associative 'plus', 'times', and 'concat' operators into the list of integers such that the resulting expression evaluates to the target value.
Note
One naive approach would be backtracking from the left:
possible?(target, x : xs) = go(x, xs) where
go(acc, []) = acc == target
go(acc, x : xs) = or([
acc + x <= target and go(acc + x, xs),
acc * x <= target and go(acc * x, xs),
concat(acc, x) <= target and go(concat(acc, x), xs)
])
You can also backtrack from the right:
possible?(target, xs) = go(target, reverse(xs)) where
go(acc, [x]) = acc == x
go(acc, x : xs) = or([
x < acc and go(acc - x, xs),
divides?(acc, x) and go(acc / x, xs),
suffix?(acc, x) and go(strip(acc, x), xs)
])
The first approach is clearer, but the advantage of the second approach is that it short-circuits earlier. The _ <= target
conditions only trigger deep into the tree, whereas divides?(acc, x)
and suffix?(acc, x)
can trigger anywhere.