Roderic Day 2 yıl önce
ebeveyn
işleme
c53feb0ec2
1 değiştirilmiş dosya ile 33 ekleme ve 46 silme
  1. +33
    -46
      y2022/p16.py

+ 33
- 46
y2022/p16.py Dosyayı Görüntüle

@@ -1,61 +1,48 @@
import collections
import itertools
import re

text = open(0).read()
import itertools


graph = collections.defaultdict(dict)
rates = {}
text = open(0).read()
graph = {}
vals = {}
for ln in text.splitlines():
source, rate, *leads_to = re.findall(r'[A-Z]{2}|\d+', ln)
for out in leads_to:
graph[out][source] = 1
graph[source][out] = 1
rates[source] = int(rate)

pos, val, *adjs = re.findall(r'[A-Z]{2}|\d+', ln)
if int(val):
vals[pos] = int(val)
graph[pos] = {k: 1 for k in adjs}
old = {k: v.copy() for k, v in graph.items()}

costs = {}
for k in graph:
edge = set(graph[k])
graph[k][k] = 0
edge = {k}
seen = set()
cost = 1
while True:
for e in edge:
if (k, e) in costs:
costs[k, e] = min(costs[k, e], cost)
else:
costs[k, e] = cost
cost += 1
edge = {n for e in edge for n in graph[e]} - seen
if seen == set(graph):
break
for step in range(1, 1000):
edge = {n for k in edge for n in old[k]} - seen
seen |= edge
for n in edge:
graph[k].setdefault(n, step)


def for_one(combo, lim):
tt = 0
bob = [0]
for a, b in zip(('AA',) + combo, combo):
tt = costs[a, b]
for _ in range(tt):
bob.append(bob[-1])
bob.append(bob[-1] + rates[b])
pending = max(0, lim - len(bob))
bob += [bob[-1]] * pending
return sum(bob[:lim])
def tic(pending, start, left):
out = []
for end in pending:
rem = max(0, left - graph[start][end] - 1)
out.append([vals[end] * rem, end, rem])
return sorted(out, reverse=True)


def generate_combos(pending, left, carry=('AA',)):
if left < 0 or not pending:
yield carry[1:]
def solve1(pending, total, pos, t_left):
if not pending:
yield total
else:
for k in pending:
yield from generate_combos(pending - {k}, left - costs[carry[-1], k], carry + (k,))
if ans1 > total + sum(vals[p] for p in pending) * t_left:
return
for contrib, pos, t_left in tic(pending, pos, t_left):
yield from solve1(pending - {pos}, total + contrib, pos, t_left)


combos = generate_combos({k for k, v in rates.items() if v}, lim=30)
best = max(combos, key=for_one)
print(best)
print(for_one(best))
# 2615
ans1 = 0
for ans in solve1(set(vals), 0, 'AA', 30):
if ans > ans1:
ans1 = ans
print(ans1)

Yükleniyor…
İptal
Kaydet