Compare commits
8 Commits
88040394db
...
cb4b8295e1
Author | SHA1 | Date | |
---|---|---|---|
cb4b8295e1 | |||
009fa446c2 | |||
47c10a1027 | |||
634e0e7eaa | |||
ee05144644 | |||
c572351a00 | |||
98ff1e0cf9 | |||
fd84db7072 |
30
day19/input
Normal file
30
day19/input
Normal file
@ -0,0 +1,30 @@
|
||||
Blueprint 1: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 13 clay. Each geode robot costs 3 ore and 7 obsidian.
|
||||
Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 12 obsidian.
|
||||
Blueprint 3: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 9 clay. Each geode robot costs 3 ore and 7 obsidian.
|
||||
Blueprint 4: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 2 ore and 11 obsidian.
|
||||
Blueprint 5: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 2 ore and 15 obsidian.
|
||||
Blueprint 6: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 3 ore and 14 obsidian.
|
||||
Blueprint 7: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 3 ore and 11 obsidian.
|
||||
Blueprint 8: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 4 ore and 19 obsidian.
|
||||
Blueprint 9: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian.
|
||||
Blueprint 10: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 17 obsidian.
|
||||
Blueprint 11: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 11 clay. Each geode robot costs 3 ore and 8 obsidian.
|
||||
Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 2 ore and 13 obsidian.
|
||||
Blueprint 13: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 13 obsidian.
|
||||
Blueprint 14: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 4 ore and 16 obsidian.
|
||||
Blueprint 15: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 15 obsidian.
|
||||
Blueprint 16: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||
Blueprint 17: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 2 ore and 9 obsidian.
|
||||
Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 3 ore and 12 obsidian.
|
||||
Blueprint 19: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 8 obsidian.
|
||||
Blueprint 20: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 4 ore and 13 obsidian.
|
||||
Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 4 ore and 8 obsidian.
|
||||
Blueprint 22: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 8 obsidian.
|
||||
Blueprint 23: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 16 obsidian.
|
||||
Blueprint 24: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian.
|
||||
Blueprint 25: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||
Blueprint 26: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 4 ore and 20 obsidian.
|
||||
Blueprint 27: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 2 ore and 13 obsidian.
|
||||
Blueprint 28: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 2 ore and 8 obsidian.
|
||||
Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 4 ore and 12 obsidian.
|
||||
Blueprint 30: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 2 ore and 16 obsidian.
|
11
day19/sample
Normal file
11
day19/sample
Normal file
@ -0,0 +1,11 @@
|
||||
Blueprint 1:
|
||||
Each ore robot costs 4 ore.
|
||||
Each clay robot costs 2 ore.
|
||||
Each obsidian robot costs 3 ore and 14 clay.
|
||||
Each geode robot costs 2 ore and 7 obsidian.
|
||||
|
||||
Blueprint 2:
|
||||
Each ore robot costs 2 ore.
|
||||
Each clay robot costs 3 ore.
|
||||
Each obsidian robot costs 3 ore and 8 clay.
|
||||
Each geode robot costs 3 ore and 12 obsidian.
|
143
day19/sol.py
Normal file
143
day19/sol.py
Normal file
@ -0,0 +1,143 @@
|
||||
import math
|
||||
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}
|
||||
|
||||
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, minutes=24):
|
||||
rmax = [max(x[i] for x in blueprint.values()) for i in range(3)] + [9999]
|
||||
|
||||
limit = None
|
||||
if minutes >= 32:
|
||||
limit = 100000
|
||||
|
||||
items = list(blueprint.items())
|
||||
items.reverse()
|
||||
|
||||
print(items)
|
||||
|
||||
buckets = [[] for _ in range(minutes+1)]
|
||||
def enqueue(t, robots, resources):
|
||||
assert t > 0
|
||||
if t <= 0 or t >= len(buckets):
|
||||
return
|
||||
x = resources[3]
|
||||
buckets[t].append((x,robots, resources))
|
||||
|
||||
enqueue(minutes, robots=[1,0,0,0], resources=[0,0,0,0])
|
||||
|
||||
max_geodes = 0
|
||||
|
||||
for _ in range(minutes):
|
||||
buckets[minutes].sort(reverse=True)
|
||||
#print(minutes, buckets[minutes][:1])
|
||||
for _, robots, resources in buckets[minutes][:limit]:
|
||||
if 1:
|
||||
geodes = robots[3]*minutes + resources[3]
|
||||
if geodes > max_geodes:
|
||||
max_geodes = geodes
|
||||
elif geodes < max_geodes:
|
||||
# if the number of geodes we could get if we stopped building robots
|
||||
# is less than the max such number we've seen so far,
|
||||
# then prune this node.
|
||||
#
|
||||
# this seems like it would be too greedy a rule, but
|
||||
# somehow it actually works. (i think this is equivalant to
|
||||
# the rule "always build a geode robot as soon as you can"
|
||||
# and its validity depends on the input data. (in fact it
|
||||
# *doesn't* work for the first sample blueprint for part 2.
|
||||
# but it works on my input so w/e)
|
||||
#
|
||||
# decreases the search space enormously
|
||||
continue
|
||||
for robot, cost in items:
|
||||
i = robot_number[robot]
|
||||
if robots[i] >= rmax[i]:
|
||||
# don't build more of 1 robot than we can spend in 1 minute
|
||||
continue
|
||||
if robot != 'geode' and robots[i]*minutes + resources[i] >= minutes*rmax[i]:
|
||||
# insight from reddit: if we have enough resources on hand and enough
|
||||
# mining capacity to build any robot that needs it every turn until
|
||||
# time is up, then we don't need to build any more of that kind of robot
|
||||
#
|
||||
# this provides a minor speed-up over just doing the simpler check
|
||||
continue
|
||||
|
||||
# figure out how soon we can afford it
|
||||
wait = 0
|
||||
for x,y,r in zip(resources, cost, robots):
|
||||
if y == 0:
|
||||
continue
|
||||
if r <= 0:
|
||||
wait = 9999
|
||||
break
|
||||
if y > x:
|
||||
wait = max(wait, int(math.ceil((y - x)/r)))
|
||||
if wait+1 >= minutes:
|
||||
continue
|
||||
|
||||
new_resources = [x+(wait+1)*r-y for x,y,r in zip(resources, cost, robots)]
|
||||
new_robots = list(robots)
|
||||
new_robots[i] += 1
|
||||
enqueue(minutes-wait-1, new_robots, new_resources)
|
||||
|
||||
print(minutes, max_geodes, [len(x) for x in buckets[:minutes+1]])
|
||||
buckets[minutes] = [] # clear old buckets to save memory
|
||||
|
||||
minutes -= 1
|
||||
|
||||
return max_geodes
|
||||
|
||||
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("blueprint", idx, "max geodes is", g)
|
||||
print("---")
|
||||
print(t)
|
||||
return t
|
||||
|
||||
def solve2(input):
|
||||
t = 1
|
||||
for idx, B in input.items():
|
||||
if idx <= 3:
|
||||
g = simulate(B, minutes=32)
|
||||
t *= g
|
||||
print(t)
|
||||
return t
|
||||
|
||||
assert solve(sample) == 33
|
||||
solve(input)
|
||||
solve2(input)
|
||||
|
5000
day20/input
Normal file
5000
day20/input
Normal file
File diff suppressed because it is too large
Load Diff
44
day20/sol.py
Normal file
44
day20/sol.py
Normal file
@ -0,0 +1,44 @@
|
||||
data = []
|
||||
for line in open("input"):
|
||||
data.append(int(line.strip()))
|
||||
|
||||
#data = [1, 2, -3, 3, -2, 0, 4, ]
|
||||
|
||||
|
||||
def mix(data, rounds=1):
|
||||
#assert len(set(data)) == len(data)
|
||||
idx = list(range(len(data)))
|
||||
N = len(data) - 1
|
||||
|
||||
for _ in range(rounds):
|
||||
|
||||
for k in range(len(data)):
|
||||
i = idx.index(k)
|
||||
x = data[k]
|
||||
if x != 0:
|
||||
j = (i+x) % N
|
||||
if x < 0 and j == 0:
|
||||
j = N
|
||||
idx.insert(j, idx.pop(i))
|
||||
else:
|
||||
j = i
|
||||
#print(x, i, j, [data[k] for k in idx])
|
||||
|
||||
return [data[k] for k in idx]
|
||||
|
||||
def answer(data):
|
||||
i = data.index(0)
|
||||
n = []
|
||||
for j in 1000, 2000, 3000:
|
||||
n.append( data[(i+j)%len(data)] )
|
||||
print(n)
|
||||
return sum(n)
|
||||
|
||||
#print(data)
|
||||
|
||||
copy = mix(data)
|
||||
print(answer(copy))
|
||||
|
||||
|
||||
p2 = [x*811589153 for x in data]
|
||||
print(answer(mix(p2, 10)))
|
Loading…
x
Reference in New Issue
Block a user