day 19 cleanup
parent
ee05144644
commit
634e0e7eaa
117
day19/sol.py
117
day19/sol.py
|
@ -1,21 +1,22 @@
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import re
|
import re
|
||||||
|
|
||||||
sample = {
|
sample = {
|
||||||
1:{
|
1:{
|
||||||
'ore': [4, 0, 0, 0],
|
'ore': [4, 0, 0, 0],
|
||||||
'clay': [2, 0, 0, 0],
|
'clay': [2, 0, 0, 0],
|
||||||
'obsidian': [3, 14, 0, 0],
|
'obsidian': [3, 14, 0, 0],
|
||||||
'geode': [2, 0, 7, 0],
|
'geode': [2, 0, 7, 0],
|
||||||
},
|
},
|
||||||
2:{
|
2: {
|
||||||
'ore': [2, 0, 0, 0],
|
'ore': [2, 0, 0, 0],
|
||||||
'clay': [3, 0, 0, 0],
|
'clay': [3, 0, 0, 0],
|
||||||
'obsidian': [3, 8, 0, 0],
|
'obsidian': [3, 8, 0, 0],
|
||||||
'geode': [3, 0, 12, 0],
|
'geode': [3, 0, 12, 0],
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
robot_number = {'ore': 0, 'clay': 1, 'obsidian': 2, 'geode': 3, 'nothing': 99}
|
robot_number = {'ore': 0, 'clay': 1, 'obsidian': 2, 'geode': 3}
|
||||||
|
|
||||||
def parse(line):
|
def parse(line):
|
||||||
line = re.sub(r'[^\d]+', ' ', line)
|
line = re.sub(r'[^\d]+', ' ', line)
|
||||||
|
@ -28,66 +29,38 @@ def parse(line):
|
||||||
}
|
}
|
||||||
|
|
||||||
def simulate(blueprint, minutes=24):
|
def simulate(blueprint, minutes=24):
|
||||||
B = blueprint
|
rmax = [max(x[i] for x in blueprint.values()) for i in range(3)] + [9999]
|
||||||
resources = [0]*4
|
|
||||||
robots = [1,0,0,0]
|
|
||||||
|
|
||||||
rmax = [max(x[i] for x in B.values()) for i in range(3)] + [99]
|
|
||||||
|
|
||||||
|
limit = None
|
||||||
|
if minutes >= 32:
|
||||||
|
limit = 100000
|
||||||
|
|
||||||
worth = {}
|
items = list(blueprint.items())
|
||||||
worth['ore'] = 1
|
items.reverse()
|
||||||
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)
|
print(items)
|
||||||
|
|
||||||
|
|
||||||
B_items = list(B.items())
|
|
||||||
B_items.reverse()
|
|
||||||
|
|
||||||
#B_items.append(('nothing', [0,0,0,0]))
|
|
||||||
|
|
||||||
print(B_items)
|
|
||||||
|
|
||||||
buckets = [[] for _ in range(minutes+1)]
|
buckets = [[] for _ in range(minutes+1)]
|
||||||
def enqueue(t, robots, resources):
|
def enqueue(t, robots, resources):
|
||||||
if t < 0 or t >= len(buckets):
|
assert t > 0
|
||||||
|
if t <= 0 or t >= len(buckets):
|
||||||
return
|
return
|
||||||
#x = (resources[3], max(resources[3], robots[3]), max(resources[2], robots[2]), max(resources[1], robots[1]), max(resources[0], robots[0]))
|
|
||||||
x = resources[3]
|
x = resources[3]
|
||||||
#w = sum(worth[r]*robots[robot_number[r]] for r in worth)
|
|
||||||
#x = tuple(reversed(resources+robots+[resources[3]]))
|
|
||||||
#x = (resources[3], robots)
|
|
||||||
#n = sum(x==0 for x in robots)
|
|
||||||
#if n == 3:
|
|
||||||
# x = (resources[0], robots[0])
|
|
||||||
#elif n == 2:
|
|
||||||
# x = (resources[1], resources[0], robots[1], robots[0])
|
|
||||||
#elif n == 1:
|
|
||||||
# x = (robots[3], min(resources[2],resources[0]), max(resources[2],resources[1]), robots[2], robots[1],robots[0])
|
|
||||||
#else:
|
|
||||||
# x = (resources[3], min(resources[2],resources[0]), max(resources[2],resources[0]), resources[1])
|
|
||||||
buckets[t].append((x,robots, resources))
|
buckets[t].append((x,robots, resources))
|
||||||
|
|
||||||
enqueue(minutes, robots, resources)
|
enqueue(minutes, robots=[1,0,0,0], resources=[0,0,0,0])
|
||||||
del resources
|
|
||||||
del robots
|
|
||||||
|
|
||||||
max_geodes = 0
|
max_geodes = 0
|
||||||
|
|
||||||
for _ in range(minutes):
|
for _ in range(minutes):
|
||||||
#next = [[] for _ in range(4)]
|
|
||||||
buckets[minutes].sort(reverse=True)
|
buckets[minutes].sort(reverse=True)
|
||||||
print(minutes, buckets[minutes][:1])
|
#print(minutes, buckets[minutes][:1])
|
||||||
for _, robots, resources in buckets[minutes][:100000]:
|
for _, robots, resources in buckets[minutes][:limit]:
|
||||||
can_build = 0
|
|
||||||
if robots[3]:
|
if robots[3]:
|
||||||
geodes = robots[3]*minutes + resources[3]
|
geodes = robots[3]*minutes + resources[3]
|
||||||
if geodes > max_geodes:
|
if geodes > max_geodes:
|
||||||
max_geodes = geodes
|
max_geodes = geodes
|
||||||
for robot, cost in B_items:
|
for robot, cost in items:
|
||||||
i = robot_number[robot]
|
i = robot_number[robot]
|
||||||
if robots[i] >= rmax[i]:
|
if robots[i] >= rmax[i]:
|
||||||
# don't build more of 1 robot than we can spend in 1 minute
|
# don't build more of 1 robot than we can spend in 1 minute
|
||||||
|
@ -103,39 +76,20 @@ def simulate(blueprint, minutes=24):
|
||||||
break
|
break
|
||||||
if y > x:
|
if y > x:
|
||||||
wait = max(wait, int(math.ceil((y - x)/r)))
|
wait = max(wait, int(math.ceil((y - x)/r)))
|
||||||
if wait > minutes:
|
if wait+1 >= minutes:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
new_resources = [x+(wait+1)*r-y for x,y,r in zip(resources, cost, robots)]
|
new_resources = [x+(wait+1)*r-y for x,y,r in zip(resources, cost, robots)]
|
||||||
if robot != 'nothing':
|
new_robots = list(robots)
|
||||||
new_robots = list(robots)
|
new_robots[i] += 1
|
||||||
new_robots[i] += 1
|
|
||||||
else:
|
|
||||||
new_robots = robots
|
|
||||||
enqueue(minutes-wait-1, new_robots, new_resources)
|
enqueue(minutes-wait-1, new_robots, new_resources)
|
||||||
#print(len(next))
|
|
||||||
|
|
||||||
#limit = 2500
|
print(minutes, max_geodes, [len(x) for x in buckets[:minutes+1]])
|
||||||
|
buckets[minutes] = [] # clear old buckets to save memory
|
||||||
#q = []
|
|
||||||
#for bucket in next:
|
|
||||||
# bucket.sort(reverse=True)
|
|
||||||
# q.extend(bucket[:limit])
|
|
||||||
|
|
||||||
#count = sum(len(b) for b in next)
|
|
||||||
#print(count, q[:1])
|
|
||||||
print(minutes, [len(x) for x in buckets])
|
|
||||||
buckets[minutes] = []
|
|
||||||
|
|
||||||
minutes -= 1
|
minutes -= 1
|
||||||
|
|
||||||
#print(buckets)
|
|
||||||
#q = buckets[0]
|
|
||||||
#print(q[0])
|
|
||||||
#return q[0][-1][-1]
|
|
||||||
return max_geodes
|
return max_geodes
|
||||||
|
|
||||||
#simulate(blueprints[1])
|
|
||||||
|
|
||||||
input = {}
|
input = {}
|
||||||
with open('input') as f:
|
with open('input') as f:
|
||||||
|
@ -148,7 +102,7 @@ def solve(input):
|
||||||
for idx, B in input.items():
|
for idx, B in input.items():
|
||||||
g = simulate(B)
|
g = simulate(B)
|
||||||
t += idx*g
|
t += idx*g
|
||||||
print(idx, g)
|
print("blueprint", idx, "max geodes is", g)
|
||||||
print("---")
|
print("---")
|
||||||
print(t)
|
print(t)
|
||||||
return t
|
return t
|
||||||
|
@ -162,6 +116,7 @@ def solve2(input):
|
||||||
print(t)
|
print(t)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
#assert solve(sample) == 33
|
assert solve(sample) == 33
|
||||||
|
#solve(input)
|
||||||
solve2(input)
|
solve2(input)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue