Files
advent-of-code/2022/11/part2
2022-12-11 14:59:39 +00:00

63 lines
2.0 KiB
Python
Executable File

#!/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'])