#!/usr/bin/env python3 import sys, re from copy import deepcopy from functools import reduce from operator import mul def parse_monkey(m): name = int(re.compile(r"Monkey (?P\d):").search(m).group('name')) items = eval('[' + re.compile(r"Starting items: (?P(\d+(, )?)+)").search(m).group('item') + ']') expr = re.compile(r"Operation: new = (?P.+)").search(m).group('op') test = int(re.compile(r"Test: divisible by (?P\d+)").search(m).group('num')) true = int(re.compile(r"If true: throw to monkey (?P\d)").search(m).group('name')) false = int(re.compile(r"If false: throw to monkey (?P\d)").search(m).group('name')) inspect = 0 dic = locals() dic.pop('m',None) return dic def roun(ms,worry,cap): for m in ms: while m['items']: old = m['items'].pop(0) new = eval(m['expr']) // (3 if not worry else 1) % cap if (new % m['test']) == 0: ms[m['true']]['items'].append(new) else: ms[m['false']]['items'].append(new) m['inspect'] = m['inspect'] + 1 if __name__ == '__main__': start_monkeys = [parse_monkey(mon) for mon in open(sys.argv[1]).read().split('\n\n')] highest = reduce(mul,[m['test'] for m in start_monkeys]) # challenge 1 monkeys = deepcopy(start_monkeys) for _ in range(20): roun(monkeys,False,highest) busy = sorted([m['inspect'] for m in monkeys], reverse=True) res1 = str(busy[0] * busy[1]) print("challenge 1:" + "\n" + res1 + "\n") # challenge 2 monkeys = deepcopy(start_monkeys) for i in range(10000): roun(monkeys,True,highest) busy = sorted([m['inspect'] for m in monkeys], reverse=True) res2 = str(busy[0] * busy[1]) print("challenge 2:" + "\n" + res2 + "\n")