Skip to content
advent of code 2022

day 21

monkey math

approach

each monkey is either a number or an operation on two other monkeys. a topological sort (kahn's algorithm, using incoming-edge counts) orders them so every monkey comes after its operands, and that order is used to build an expression tree of Nodes. part 1 evaluates the tree from the root.

part 2 makes humn the unknown. the code finds which side of the root contains it, evaluates the other side, and then walks down the path to humn, undoing one operation at each step: on the side without the unknown it evaluates the subtree, and applies the inverse operation to the target value. subtraction and division need care when the unknown is on the right, so those two cases use the original operator with the operands swapped. an assert checks that both sides of the root match at the end. a commented-out version that compiled the whole tree into one python function is left in the file.

the trick

only one path in the tree depends on humn, so solving for it is a walk down that path, inverting each operation.

python
def regression(node, result):
    if node.val == "humn":
        return result
    if has_humn(node.left):
        other = eval_tree(node.right)
        r = regression(node.left, ex(inv(node.val), result, other))
    else:
        other = eval_tree(node.left)
        if node.val in "/-":
            r = regression(node.right, ex(node.val, other, result))
        else:
            r = regression(node.right, ex(inv(node.val), result, other))
    return r