#!/usr/bin/env python3 import sys from copy import deepcopy from math import prod from operator import add, mul def monkey_business(monkeys, rounds, part2): monkeys = deepcopy(monkeys) ohmygodihateyoueric = prod(m["test"] for m in monkeys) for it in range(rounds): for m in monkeys: for old in m["items"]: m["count"] += 1 new = m["op"](old) if part2: new %= ohmygodihateyoueric else: new //= 3 monkeys[m[not (new % m["test"])]]["items"].append(new) m["items"].clear() return prod(sorted(m["count"] for m in monkeys)[-2:]) def op2func(opstr): params = opstr.split() op = add if params[1] == "+" else mul if params[2] == "old": func = lambda old: op(old, old) else: func = lambda old: op(old, int(params[2])) return func monkeys = [] for a, b in [l.strip().split(":") for l in sys.stdin if ":" in l]: match a.split(): case ["Monkey", _]: monkeys.append({}) monkeys[-1]["count"] = 0 case ["Starting", "items"]: monkeys[-1]["items"] = [int(x) for x in b.split(", ")] case ["Operation"]: monkeys[-1]["op"] = op2func(b.split(" = ")[1]) case ["Test"]: monkeys[-1]["test"] = int(b.rsplit(" ", 1)[-1]) case ["If", condition]: monkeys[-1][condition == "true"] = int(b.rsplit(" ", 1)[-1]) p1 = monkey_business(monkeys, 20, False) p2 = monkey_business(monkeys, 10000, True) print(f"Silver: {p1}\nGold: {p2}")