day 11
monkey in the middle
approach
each monkey's block is parsed into a Monkey with a deque of items, its operation (the expression is passed to eval with old bound), its divisor and the two targets. a round lets each monkey inspect and throw all its items, counting inspections; the answer is the product of the two largest counts.
part 1 runs 20 rounds and divides the worry by 3 after each inspection. part 2 runs 10,000 rounds without dividing, so the numbers would grow without bound. every thrown value is reduced modulo the lcm of all the divisors, which leaves every divisibility test unchanged.
the trick
all the tests are divisibility checks, so worry levels can live modulo the lcm of the divisors.
python
# mutates monkeys
def round(monkeys, divide, mult):
for i, monkey in monkeys.items():
for m, nw in monkey.round(divide):
monkeys[m].add(nw % mult)