aoc
/
2022
1
0
Fork 0
2022/day11.py

77 lines
1.9 KiB
Python

import sys
from pprint import pprint
from dataclasses import dataclass
from functools import reduce
from typing import List
import operator
@dataclass
class Monke:
operation: str
param: str
divisible_by: int
if_true: int
if_false: int
inputs = [l.split("\n") for l in sys.stdin.read().split("\n\n")]
monkeys: List[Monke] = []
items = []
inspections = []
visited = []
for monkey in inputs:
items.append(tuple(int(x) for x in monkey[1][18:].split(", ")))
inspections.append(0)
visited.append({})
op, param = monkey[2].split()[4:]
divisible_by = int(monkey[3].split()[-1])
if_true = int(monkey[4].split()[-1])
if_false = int(monkey[5].split()[-1])
monkeys.append(Monke(op, param, divisible_by, if_true, if_false))
def do_round():
for m, monke in enumerate(monkeys):
# print("Monke", m, monke.items)
for item in items[m]:
inspections[m] += 1
# print(" W :=", item)
param = item if monke.param == "old" else int(monke.param)
if monke.operation == "*":
item *= param
# print(" W *", param, "=", item)
elif monke.operation == "+":
item += param
# print(" W +", param, "=", item)
else:
assert False
item //= 3
# print(" W / 3 =", item)
divisible = item % monke.divisible_by == 0
# print(" W %", monke.divisible_by, "== 0 =", divisible)
target = monke.if_true if divisible else monke.if_false
# print(" Thrown to", target)
items[target] = (*items[target], item)
items[m] = ()
for i in range(20):
do_round()
print(reduce(operator.mul, sorted(inspections)[-2:]))
# for i in range(20, 10_000):
# if i % 100 == 0: print(i)
# do_round()
print(reduce(operator.mul, sorted(inspections)[-2:]))