adventofcode2022/day19/sol.py

117 lines
3.0 KiB
Python
Raw Normal View History

2022-12-19 07:08:55 +00:00
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)