adventofcode2022/day11/sol.py

71 lines
2.0 KiB
Python
Raw Normal View History

2022-12-11 06:18:04 +00:00
from collections import Counter, namedtuple
2022-12-11 07:38:51 +00:00
from copy import deepcopy
2022-12-11 06:18:04 +00:00
import math
Monkey = namedtuple('Monkey', 'index, op, divisor, target')
2022-12-11 05:32:55 +00:00
def parse(input):
monkeys = []
2022-12-11 06:18:04 +00:00
items = {}
for i, chunk in enumerate(input.split("\n\n")):
2022-12-11 05:32:55 +00:00
lines = chunk.strip().split("\n")
2022-12-11 06:18:04 +00:00
assert 'Starting items:' in lines[1]
assert 'Operation: new =' in lines[2]
assert 'Test: divisible by' in lines[3]
assert 'If true: throw to' in lines[4]
assert 'If false: throw to' in lines[5]
items[i] = [int(x.strip()) for x in lines[1].split(":")[1].split(",")]
2022-12-11 05:32:55 +00:00
op = eval("lambda old: " + lines[2].split("=")[1])
divisor = int(lines[3].split()[-1])
target = [
int(lines[5].split()[-1]),
int(lines[4].split()[-1]),
]
2022-12-11 07:38:51 +00:00
monkeys.append(Monkey(i, op, divisor, target))
2022-12-11 06:18:04 +00:00
return monkeys, items
2022-12-11 05:32:55 +00:00
2022-12-11 06:18:04 +00:00
def play(monkeys, items, rounds=1, N=None):
throws = Counter()
for _ in range(rounds):
2022-12-11 07:38:51 +00:00
for m in monkeys:
for x in items[m.index]:
2022-12-11 06:18:04 +00:00
if N:
nx = m.op(x) % N
else:
nx = m.op(x) // 3
trg = m.target[nx % m.divisor == 0]
#print(f'{i}: {x} -> {nx}. throwing to {trg}')
items[trg].append(nx)
2022-12-11 07:38:51 +00:00
throws[m.index] += len(items[m.index])
items[m.index] = []
show(items)
2022-12-11 05:32:55 +00:00
return throws
2022-12-11 06:18:04 +00:00
def show(items):
for k in items:
print(k, items[k])
def monkeybusiness(throws):
a, b = [x[1] for x in throws.most_common(2)]
return a*b
def lcm(ints):
n = 1
for x in ints:
n *= x // math.gcd(n, x)
return n
def main():
monkeys, items = parse(open("input").read())
#print(monkeys)
show(items)
2022-12-11 07:38:51 +00:00
throws = play(monkeys, deepcopy(items), rounds=20)
2022-12-11 06:18:04 +00:00
print(monkeybusiness(throws))
N = lcm(m.divisor for m in monkeys)
2022-12-11 07:38:51 +00:00
throws = play(monkeys, deepcopy(items), rounds=10000, N=N)
2022-12-11 06:18:04 +00:00
print(monkeybusiness(throws))
main()