summaryrefslogtreecommitdiffstats
path: root/11.py
blob: 0187a9b19acaeb6f012976c72fbb13cde3503496 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from copy import deepcopy
from dataclasses import dataclass
from functools import partial, reduce
from operator import mul as mul_op
from typing import Callable

def identity(o):
    return o
def value(v, _):
    return v
def add(a, b, o):
    return a(o) + b(o)
def mul(a, b, o):
    return a(o) * b(o)

@dataclass
class Monkey:
    items: list[int]
    op: Callable[[int], int]
    test_div: int
    target: tuple[int, int]
    inspections: int = 0
    def from_str(s):
        items, op, test_div, true_tgt, false_tgt = [l.split(': ')[1] for l in s.split('\n')[1:]]
        items = [int(i) for i in items.split(', ')]
        op = op.split(' ')[2:]
        lhs = identity if op[0] == 'old' else partial(value, int(op[0]))
        rhs = identity if op[2] == 'old' else partial(value, int(op[2]))
        op = partial(add, lhs, rhs) if op[1] == '+' else partial(mul, lhs, rhs)
        test_div = int(test_div.split(' ')[-1])
        true_tgt = int(true_tgt.split(' ')[-1])
        false_tgt = int(false_tgt.split(' ')[-1])
        return Monkey(items, op, test_div, (true_tgt, false_tgt))

with open('11.in') as f:
    monkeys = [Monkey.from_str(m) for m in f.read().rstrip().split('\n\n')]


def solve(monkeys, rounds, do_div):
    monkeys = deepcopy(monkeys)
    modulo = reduce(mul_op, (m.test_div for m in monkeys), 1)
    for _ in range(rounds):
        for m in monkeys:
            while m.items:
                m.inspections += 1
                i = m.items.pop(0)
                i = m.op(i)
                if do_div: i //= 3
                target = m.target[min(i % m.test_div, 1)]
                monkeys[target].items.append(i % modulo)
    return reduce(mul_op, sorted(m.inspections for m in monkeys)[-2:], 1)

print(solve(monkeys, 20, True))
print(solve(monkeys, 10000, False))