day 16 part 2 python, finally

ugh
main
magical 2022-12-16 10:45:46 -08:00
parent 03710f579a
commit 014b7daf09
1 changed files with 189 additions and 44 deletions

View File

@ -30,49 +30,194 @@ def save():
#import astar
score = {'AA': (0, 0, [])}
def part1():
score = {'AA': (0, 0, [])}
# find the largest reward we can get in n steps
# then find the largest reward we can get in n+1 steps
potential = sum(r for _,r,_ in G)
minutes = 30
for _ in range(minutes):
minutes -= 1
next = {}
for v, r, E in G:
vo = v + 'o'
s = []
o = []
if vo in score:
reward, flow, open = score[vo]
o.append((reward, flow, open))
if v in score:
reward, flow, open = score[v]
# stay, don't open valve
s.append((reward, flow, open))
# stay in place, open valve
if v not in open:
reward += r*minutes
o.append((reward, flow+r, open+[v]))
# move here from somewhere else
minutes = 30
for _ in range(minutes):
minutes -= 1
next = {}
for v, r, E in G:
vo = v + 'o'
s = []
o = []
if vo in score:
reward, flow, open = score[vo]
o.append((reward, flow, open))
if v in score:
reward, flow, open = score[v]
# stay, don't open valve
s.append((reward, flow, open))
# stay in place, open valve
if v not in open:
reward += r*minutes
o.append((reward, flow+r, open+[v]))
# move here from somewhere else
for e in E:
if e in score:
if v in score[e][-1]:
o.append(score[e])
else:
s.append(score[e])
eo = e+'o'
if eo in score:
if v in score[eo][-1]:
o.append(score[eo])
else:
s.append(score[eo])
if s:
next[v] = max(s)
if o:
next[vo] = max(o)
score = next
print("%d minutes left" % minutes)
for v, (r, flow, open) in sorted(score.items(), key=lambda x: x[1]):
print("\t", v, r, "\t", ",".join(open))
print(max(r for r,_,_ in score.values()))
def part2():
H = {x[0]: x for x in G}
def actions(v, open):
_, r, E = H[v]
if v in open:
yield (v, 0, [])
else:
yield (v, 0, [])
yield (v+'o', r, [v])
# move to somewhere else
for e in E:
if e in score:
if v in score[e][-1]:
o.append(score[e])
else:
s.append(score[e])
eo = e+'o'
if eo in score:
if v in score[eo][-1]:
o.append(score[eo])
else:
s.append(score[eo])
if s:
next[v] = max(s)
if o:
next[vo] = max(o)
score = next
print("%d minutes left" % minutes)
for v, (r, flow, open) in sorted(score.items(), key=lambda x: x[1]):
print("\t", v, r, "\t", ",".join(open))
print(max(r for r,_,_ in score.values()))
if e in open:
e = e+'o'
yield (e, 0, [])
score = {('AA', 'AA'): (0, 0, [])}
minutes = 26
for _ in range(minutes):
next = {}
minutes -= 1
for (me, elephant) in score:
reward, flow, open = score[(me, elephant)]
for v, r, o in actions(me.strip('o'), open):
for v1, r1, o1 in actions(elephant.strip('o'), open+o):
reward_ = reward + (r+r1)*minutes
flow_ = flow + r + r1
open_ = open + o + o1
next.setdefault((v, v1), []).append((reward_, flow_, open_))
for k in next:
next[k] = max(next[k])
score = next
print("%d minutes left" % minutes)
for v, (r, flow, open) in sorted(score.items(), key=lambda x: x[1]):
print("\t", v, r, "\t", ",".join(open))
print(max(r for r,_,_ in score.values()))
#part2()
def part2_b():
score = {'AA': (0, 0, [])}
minutes = 26
for _ in range(minutes):
minutes -= 1
next = {}
for v, r, E in G:
vo = v + 'o'
s = []
o = []
if vo in score:
reward, flow, open = score[vo]
o.append((reward, flow, open))
if v in score:
reward, flow, open = score[v]
# stay, don't open valve
s.append((reward, flow, open))
# stay in place, open valve
if v not in open:
reward += r*minutes
o.append((reward, flow+r, open+[v]))
# move here from somewhere else
for e in E:
if e in score:
if v in score[e][-1]:
o.append(score[e])
else:
s.append(score[e])
eo = e+'o'
if eo in score:
if v in score[eo][-1]:
o.append(score[eo])
else:
s.append(score[eo])
if s:
next[v] = max(s)
if o:
next[vo] = max(o)
score = next
print("%d minutes left" % minutes)
for v, (r, flow, open) in sorted(score.items(), key=lambda x: x[1]):
print("\t", v, r, "\t", ",".join(open))
maxpair = []
for r,_,open in score.values():
o = frozenset(open)
for s,_,open in score.values():
if o.isdisjoint(open):
maxpair.append(r+s)
print(max(maxpair))
#part2_b()
def part2_c():
V = sorted(v for v,_,_ in G)
B = {v: 1<<i for i, v in enumerate(V)}
E = {B[v]: [B[e] for e in edges] for v,_,edges in G}
R = {B[v]: r for v,r,_ in G}
all_open = sum(B.values())
aa = B['AA']
states = [(aa, 0, 0)]
minutes = 26
for _ in range(minutes):
print(minutes, len(states))
minutes -= 1
next = []
seen = set()
states.sort(key=lambda x: -x[2])
for v, open, reward in states:
if (v,open) in seen:
continue
seen.add((v,open))
#next.append((v, open, reward))
if open == all_open:
next.append((v, open, reward))
else:
#next.append((v, open, reward))
r = R[v]
if r and not v&open:
next.append((v, open|v, reward+r*minutes))
for e in E[v]:
next.append((e, open, reward))
states = next
print(max(r for _,_,r in states))
best = {}
for _,o,r in states:
if o in best and best[o] >= r:
continue
best[o] = r
maxpair = []
def pairs():
O = sorted(best.keys())
for i in range(len(O)):
for j in range(i,len(O)):
if not O[i] & O[j]:
yield(best[O[i]]+best[O[j]])
print(max(pairs()))
part2_c()