diff --git a/day19/sol.py b/day19/sol.py index e4528af..1936816 100644 --- a/day19/sol.py +++ b/day19/sol.py @@ -31,10 +31,8 @@ def simulate(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) + rmax = [max(x[i] for x in B.values()) for i in range(3)] + [99] - B['nothing'] = [0,0,0,0] worth = {} worth['ore'] = 1 @@ -45,19 +43,31 @@ def simulate(blueprint): print(worth) + B_items = list(B.items()) + B_items.reverse() + + B_items.append(('nothing', [0,0,0,0])) + + print(B_items) + minutes = 24 q = [(0, robots, resources)] del resources del robots for _ in range(minutes): - next = [] - seen = set() + next = [[] for _ in range(4)] for _, robots, resources in q: - for robot, cost in B.items(): + can_build = 0 + for robot, cost in B_items: i = robot_number[robot] if robot != 'nothing' and robots[i] >= rmax[i]: + # don't build more of 1 robot than we can spend in 1 minute + continue + if robot == 'nothing' and can_build == 3: + # always build something unless continue if not all(x >= y for x, y in zip(resources, cost)): + # can't afford continue new = [] @@ -69,29 +79,38 @@ def simulate(blueprint): 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)) + x = (new[3], max(new[3], new_robots[3]), max(new[2], new_robots[2]), max(new[1], new_robots[1]), max(new[0], new_robots[0])) + #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) + n = sum(x==0 for x in new_robots) + if n == 3: + x = (new[0], new_robots[0]) + elif n == 2: + x = (new[1], new[0], new_robots[1], new_robots[0]) + elif n == 1: + x = (new_robots[3], min(new[2],new[0]), max(new[2],new[1]), new_robots[2], new_robots[1],new_robots[0]) + else: + x = (new[3], min(new[2],new[0]), max(new[2],new[0]), new[1]) + next[n].append((x,new_robots,new)) + can_build += 1 + if robot == 'geode': + # if we can build a geode then don't bother building anything else + break + #print(len(next)) - bucket = {} - for x,rob,res in next: - bucket.setdefault(x[0],[]).append((x,rob,res)) + limit = 2500 q = [] - for i in bucket: - bucket[i].sort(reverse=True) - q.extend(bucket[i][:2000]) + for bucket in next: + bucket.sort(reverse=True) + q.extend(bucket[:limit]) - bucket.clear() - - print(len(q), q[:1]) + count = sum(len(b) for b in next) + print(count, q[:1]) print(q[0]) - return q[0][2][3] + return q[0][-1][-1] #simulate(blueprints[1])