day 11 python cleanup

main
magical 2022-12-10 22:18:04 -08:00
parent eefab8eabf
commit 4fc545ac39
1 changed files with 59 additions and 42 deletions

View File

@ -1,54 +1,71 @@
from collections import Counter from collections import Counter, namedtuple
import math
Monkey = namedtuple('Monkey', 'index, op, divisor, target')
def parse(input): def parse(input):
if hasattr(input, 'read'):
input = input.read()
monkeys = [] monkeys = []
for chunk in input.split("\n\n"): items = {}
for i, chunk in enumerate(input.split("\n\n")):
lines = chunk.strip().split("\n") lines = chunk.strip().split("\n")
assert 'Starting' in lines[1] assert 'Starting items:' in lines[1]
items = [int(x.strip()) for x in lines[1].split(":")[1].split(",")] assert 'Operation: new =' in lines[2]
assert 'Operation' 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(",")]
op = eval("lambda old: " + lines[2].split("=")[1]) op = eval("lambda old: " + lines[2].split("=")[1])
assert 'divisible by' in lines[3]
divisor = int(lines[3].split()[-1]) divisor = int(lines[3].split()[-1])
assert 'true: throw' in lines[4]
assert 'false: throw' in lines[5]
target = [ target = [
int(lines[5].split()[-1]), int(lines[5].split()[-1]),
int(lines[4].split()[-1]), int(lines[4].split()[-1]),
] ]
monkeys.append(Monkey(items, op, divisor, target))
return monkeys, items
monkeys.append((items, op, divisor, target)) def play(monkeys, items, rounds=1, N=None):
return monkeys
def product(it):
t = 1
for x in it:
t *= x
return t
throws = Counter() throws = Counter()
def play(monkeys): for _ in range(rounds):
N = product(m[2] for m in monkeys)
for i, m in enumerate(monkeys): for i, m in enumerate(monkeys):
items, op, divisor, target = m for j, x in enumerate(items[i]):
for j, x in enumerate(items): if N:
throws[i] += 1 nx = m.op(x) % N
old = x else:
x = op(x) nx = m.op(x) // 3
#x //= 3 trg = m.target[nx % m.divisor == 0]
x %= N #print(f'{i}: {x} -> {nx}. throwing to {trg}')
trg = target[x % divisor == 0] items[trg].append(nx)
#print(f'{old} -> {x}. throwing to {trg}') throws[i] += len(items[i])
monkeys[trg][0].append(x) items[i] = []
items[:] = []
return throws return throws
m = parse(open("input")) def show(items):
print(m) for k in items:
for _ in range(10000): print(k, items[k])
play(m)
for i, m in enumerate(m): def monkeybusiness(throws):
print(i, m[0]) a, b = [x[1] for x in throws.most_common(2)]
a, b = sorted(throws.values())[-2:] return a*b
print(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)
tmp = {i: list(xs) for i, xs in items.items()}
throws = play(monkeys, tmp, rounds=20)
show(tmp)
print(monkeybusiness(throws))
N = lcm(m.divisor for m in monkeys)
throws = play(monkeys, items, rounds=10000, N=N)
show(items)
print(monkeybusiness(throws))
main()