import re sample = { 1:{ 'ore': [4, 0, 0, 0], 'clay': [2, 0, 0, 0], 'obsidian': [3, 14, 0, 0], 'geode': [2, 0, 7, 0], }, 2:{ 'ore': [2, 0, 0, 0], 'clay': [3, 0, 0, 0], 'obsidian': [3, 8, 0, 0], 'geode': [3, 0, 12, 0], }} robot_number = {'ore': 0, 'clay': 1, 'obsidian': 2, 'geode': 3, 'nothing': 99} def parse(line): line = re.sub(r'[^\d]+', ' ', line) idx, ore1, ore2, ore3, clay3, ore4, obs4 = map(int, line.split()) return idx, { 'ore': [ore1, 0,0,0], 'clay': [ore2, 0,0,0], 'obsidian': [ore3,clay3,0,0], 'geode': [ore4,0,obs4,0], } def simulate(blueprint): B = blueprint resources = [0]*4 robots = [1,0,0,0] rmax = [max(x[i] for x in B.values()) for i in range(3)] rmax.append(99) B['nothing'] = [0,0,0,0] worth = {} worth['ore'] = 1 worth['clay'] = worth['ore']*B['clay'][0] worth['obsidian'] = worth['ore']*B['obsidian'][0] + worth['clay']*B['obsidian'][1] worth['geode'] = worth['ore']*B['geode'][0] + worth['obsidian']*B['geode'][2] print(worth) minutes = 24 q = [(0, robots, resources)] del resources del robots for _ in range(minutes): next = [] seen = set() for _, robots, resources in q: for robot, cost in B.items(): i = robot_number[robot] if robot != 'nothing' and robots[i] >= rmax[i]: continue if not all(x >= y for x, y in zip(resources, cost)): continue new = [] for x,y,z,m in zip(resources, robots, cost, rmax): x = x+y-z new.append(x) if robot != 'nothing': new_robots = list(robots) new_robots[i] += 1 else: new_robots = robots key = str(new_robots)+str(new) if key not in seen: #x = (new[3], new_robots[3], new[2] + new[0], new_robots[2] + new_robots[0], new[1]+new[0], new_robots[1]+new_robots[0], new, new_robots) w = sum(worth[r]*robots[robot_number[r]] for r in worth) x = tuple(reversed(new+new_robots+[new[3]])) #x = (new[3], new_robots) next.append((x, new_robots, new)) bucket = {} for x,rob,res in next: bucket.setdefault(x[0],[]).append((x,rob,res)) q = [] for i in bucket: bucket[i].sort(reverse=True) q.extend(bucket[i][:2000]) bucket.clear() print(len(q), q[:1]) print(q[0]) return q[0][2][3] #simulate(blueprints[1]) input = {} with open('input') as f: for line in f: idx, bp = parse(line) input[idx] = bp def solve(input): t = 0 for idx, B in input.items(): g = simulate(B) t += idx*g print(idx, g) print("---") print(t) return t assert solve(sample) == 33 solve(input)