63 lines
2.0 KiB
Plaintext
63 lines
2.0 KiB
Plaintext
|
#!/usr/bin/env python
|
||
|
|
||
|
import re
|
||
|
import math
|
||
|
|
||
|
MONKEYS = []
|
||
|
|
||
|
def parse_factor(old, factor):
|
||
|
if factor == 'old':
|
||
|
return old
|
||
|
|
||
|
return int(factor)
|
||
|
|
||
|
OPS = {
|
||
|
'*': lambda old, factor: old * parse_factor(old, factor),
|
||
|
'+': lambda old, factor: old + parse_factor(old, factor),
|
||
|
}
|
||
|
|
||
|
with open('input') as f:
|
||
|
monkey = {'inspections': 0}
|
||
|
|
||
|
for line in f:
|
||
|
if line == "\n":
|
||
|
MONKEYS.append(monkey)
|
||
|
monkey = {'inspections': 0}
|
||
|
elif match := re.match('^Monkey (\d+):$', line):
|
||
|
monkey['id'] = int(match[1])
|
||
|
elif match := re.match('^ Starting items:', line):
|
||
|
_, items = line.rstrip().split(":")
|
||
|
monkey['items'] = list(map(int, items.split(", ")))
|
||
|
elif match := re.match('^ Operation: new = old ([\*\+]) (\w+)', line):
|
||
|
monkey['op_op'] = match[1]
|
||
|
monkey['op_factor'] = match[2]
|
||
|
elif match := re.match('^ Test: divisible by (\d+)$', line):
|
||
|
monkey['test_factor'] = int(match[1])
|
||
|
elif match := re.match('^ If (true|false): throw to monkey (\d+)$', line):
|
||
|
monkey['test_'+match[1]] = int(match[2])
|
||
|
else:
|
||
|
raise Exception('unhandled line: '+line)
|
||
|
MONKEYS.append(monkey)
|
||
|
|
||
|
for idx, monkey in enumerate(MONKEYS):
|
||
|
assert(idx == monkey['id'])
|
||
|
|
||
|
# keep the size of the numbers down
|
||
|
lcm = math.lcm(*map(lambda monkey: monkey['test_factor'], MONKEYS))
|
||
|
|
||
|
for r in range(0,10000): # round
|
||
|
for monkey in MONKEYS: # turn
|
||
|
for item in monkey['items']:
|
||
|
item = OPS[monkey['op_op']](item, monkey['op_factor'])
|
||
|
item = item % lcm
|
||
|
if item % monkey['test_factor'] == 0:
|
||
|
MONKEYS[monkey['test_true']]['items'].append(item)
|
||
|
else:
|
||
|
MONKEYS[monkey['test_false']]['items'].append(item)
|
||
|
monkey['inspections'] = monkey['inspections'] + 1
|
||
|
monkey['items'] = []
|
||
|
|
||
|
by_inspections = sorted(MONKEYS, key=lambda monkey: monkey['inspections'])
|
||
|
|
||
|
print(by_inspections[-1]['inspections'] * by_inspections[-2]['inspections'])
|