| import functools | |||||
| import operator | |||||
| import re | |||||
| class Monkey: | |||||
| def __init__(self, description): | |||||
| relevant = re.findall(r'\d+|old|\*|\+', description) | |||||
| parsed = [int(n) if n.isdigit() else n for n in relevant] | |||||
| self.idx, *self.items, _, op, op_arg, self.div, aa, bb = parsed | |||||
| op = {'*': operator.mul, '+': operator.add}[op] | |||||
| self.fn = lambda x: op(x, x if op_arg == 'old' else op_arg) | |||||
| self.target = lambda x: aa if x % self.div == 0 else bb | |||||
| def __repr__(self): | |||||
| return f'Monkey_{self.idx}({self.items})' | |||||
| def play(monkeys, n_rounds, act): | |||||
| counts = [0 for _ in monkeys] | |||||
| for _ in range(n_rounds): | |||||
| for monkey in monkeys: | |||||
| while monkey.items: | |||||
| counts[monkey.idx] += 1 | |||||
| item = act(monkey, monkey.items.pop()) | |||||
| monkeys[monkey.target(item)].items.append(item) | |||||
| yy, zz = sorted(counts)[-2:] | |||||
| return yy * zz | |||||
| text = open(0).read() | |||||
| monkeys = [Monkey(descr) for descr in text.strip().split('\n\n')] | |||||
| ans1 = play(monkeys, 20, lambda m, i: int(m.fn(i) / 3)) | |||||
| print(ans1) | |||||
| monkeys = [Monkey(descr) for descr in text.strip().split('\n\n')] | |||||
| lim = functools.reduce(operator.mul, [m.div for m in monkeys]) | |||||
| ans2 = play(monkeys, 10_000, lambda m, i: m.fn(i) % lim) | |||||
| print(ans2) |