Metadata
-
Date
-
Tagged
-
Part of series
- Advent of Code 2022 Day 1
- Advent of Code 2022 Day 2
- Advent of Code 2022 Day 3
- Advent of Code 2022 Day 4
- Advent of Code 2022 Day 5
- Advent of Code 2022 Day 6
- Advent of Code 2022 Day 7
- Advent of Code 2022 Day 8
- Advent of Code 2022 Day 9
- Advent of Code 2022 Day 10
- Advent of Code 2022 Day 11
- Advent of Code 2022 Day 12
- Advent of Code 2022 Day 13
- Advent of Code 2022 Day 14
- Advent of Code 2022 Day 15
- Advent of Code 2022 Day 16
- Advent of Code 2022 Day 17
- Advent of Code 2022 Day 18
- Advent of Code 2022 Day 19
- Advent of Code 2022 Day 20
- Advent of Code 2022 Day 21
- Advent of Code 2022 Day 22
- Advent of Code 2022 Day 23
- Advent of Code 2022 Day 24
- Advent of Code 2022 Day 25
-
Older post
-
Newer post
Advent of Code 2022 Day 21
Day 21: Monkey Math
https://adventofcode.com/2022/day/21
The monkeys are back.
Loud bunch. They do one of two things:
- Yell a number
- Yell the result of a math operation
The number monkeys know their number from the start
The operation monkeys know their operator and names of 2 other monkeys whose number they should operate on. Once they can do their operation, they yell the result.
An example input looks like this:
Before the colon is the name of the monkey.
After the colon is either a number, or an operation that depends on the results of 2 other monkeys.
Parsing
I chose to parse every monkey as a variant of a Monkey
enum.
- It’s either
Num
, and knows 1 thing:- A number
- Or it’s
Calculated
, and knows 3 things:- The name of the left-hand side monkey
- An operator
- The name of the right-hand side monkey.
The parsing function takes a parameter this time, a reference to the input string. The reasons are unimportant (for this post), and Rust specific (yay, lifetimes).
It turns every line into a Monkey
, and collects them all into a map that maps names to monkeys.
So for the example if I look up "root"
, that maps returns Monkey::Calculated(Operator::Add, "pppw", "sjmn")
.
Part 1
The question asks what number the monkey named “root” will yell?
Funny name for a monkey, but alright. (it’s a hint we’re dealing with a graph problem here, it’s the root node of a tree)
The answer: RECURSION!
Recursion is a bit mindbendy to get your head around at first. Computerphile did a gread video on it with an explanation:
Helpers
So a recursive helper function that evaluates a Monkey
’s number given a name.
If the monkey with name
is a Monkey::Num
, return the num it holds.
If the monkey with name
is a Monkey::Calculated
:
- Calculate the
lhs
number using that same helper function, this time passing inlhs
asname
parameter. - Calculate the
rhs
number using that same helper function, this time passing inrhs
asname
parameter. - return the result of applying the
Operation
tolhs_num
andrhs_num
.
With that, part1 boils down to calling calc_name
with "root"
as name
.
Final code
Part 2
Woopsie! The job for the monkey named "root"
was wrong.
It’s actually checking for equality between the 2 monkeys it has as lhs
and rhs
.
Also, the monkey named humn
isn’t a monkey at all, it’s you!
The input has humn
as shouting a number, but it’s wrong.
The question asks what number "humn"
needs to yell to make "root"
’s equality check pass.
The “root” monkey depends on 2 other monkeys. Only one of those 2 can ever depend on “humn”. The other one can be calculated using the helper from part1.
Helpers
A function that determines if a monkey needs to know the “humn” number to calculate their number.
Again, recurse if the monkey is a Calculated
one.
If either its lhs
or rhs
depend on “humn”, it depends on “humn” too.
The next helper is a function that calculates the value a monkey should say, if the calculated name
and the passed value
should be equal.
For example.
If you pass in "root"
and 10
.
It will return the value "humn"
should say in order for "root"
to evaluate to 10
.
This is done by first calculating the monkey (lhs
or rhs
) that doesn’t depends on "humn"
and evaluating it.
Then reordering the equation the passed in (name
) monkey does to solve for the only remaining unknown (the side that depends on "humn"
).
A different example:
-
Monkey with name
"aaa"
should have a value of10
. -
"aaa"
is aCalculated
monkey that adds"bbb"
and"ccc"
. -
"bbb"
evaluates to 4 -
"ccc"
depends on"humn"
and remains unknown. -
"aaa"
=10
-
"aaa"
="bbb"
+"ccc"
Plugging in the calculated number for "aaa"
:
10
="bbb"
+"ccc
Plugging in the calculated number for "bbb"
:
10
=4
+"ccc
That means we can calculate what "ccc"
has to be.
"ccc"
=10
-4
=6