| import re | |||||
| order = ['ore', 'clay', 'obsidian', 'geode'] | |||||
| blueprints = [] | |||||
| for ln in open(0).read().split('Blueprint')[1:]: | |||||
| costs = [] | |||||
| for ln in [re.findall(r'(\d+) (\w+)', part) for part in ln.split('Each')[1:]]: | |||||
| cost = [0, 0, 0, 0] | |||||
| for qty, kind in ln: | |||||
| cost[order.index(kind)] = int(qty) | |||||
| costs.append(tuple(cost)) | |||||
| blueprints.append(tuple(costs)) | |||||
| def evolve(bots, ores, choice, blueprint, lims): | |||||
| if all(o >= b for o, b in zip(ores, blueprint[3])) and choice != 3: | |||||
| return | |||||
| if choice != -1: | |||||
| ores = tuple(a - b for a, b in zip(ores, blueprint[choice])) | |||||
| if any(a < 0 for a in ores): | |||||
| return | |||||
| ores = tuple(a + b for a, b in zip(ores, bots)) | |||||
| if choice != -1: | |||||
| bots = tuple(a + (choice == i) for i, a in enumerate(bots)) | |||||
| if any(q > l for q, l in zip(bots, lims[:-1])): | |||||
| return | |||||
| yield (bots, ores) | |||||
| def solve(blueprint): | |||||
| states = {((1, 0, 0, 0), (0, 0, 0, 0))} | |||||
| lims = list(map(max, zip(*blueprint))) | |||||
| for _ in range(24): | |||||
| print('.', end='') | |||||
| states = {new for old in states for choice in [-1, 0, 1, 2, 3] for new in evolve(*old, choice, blueprint, lims)} | |||||
| best = max(s[0][-1] for s in states) | |||||
| states = {s for s in states if best - s[0][-1] < 2} | |||||
| print() | |||||
| return max(states, key=lambda state: state[-1][-1]) | |||||
| ans1 = 0 | |||||
| ans2 = 1 | |||||
| for idx, bp in enumerate(blueprints, 1): | |||||
| state = solve(bp) | |||||
| ans1 += idx * state[-1][-1] | |||||
| ans2 *= state[-1][-1] | |||||
| print(idx, ans1, state[-1][-1]) | |||||
| print(ans1) | |||||
| print(ans2) |