#!/usr/bin/env python3 import sys, re from copy import deepcopy VALVES = {'V': [], 'E': [], 'w': {}} def parse(line): g = re.compile(r"Valve (?P\w{2}) has flow rate=(?P\d+); tunnel(s)? lead(s)? to valve(s)? (?P(\w{2}(, )?)*)").search(line) vc = g.group('valve') + 'C' vo = g.group('valve') + 'O' es = g.group('tunnel').split(', ') VALVES['V'] += [vc,vo] VALVES['E'].append((vc,vo)) for e in es: VALVES['E'].append((vo,e+'C')) VALVES['E'].append((vc,e+'C')) VALVES['w'][(vo,e+'C')] = 0 VALVES['w'][(vc,e+'C')] = 0 VALVES['w'][(vc,vo)] = int(g.group('fr')) def Init(G,s,k): d = {} o = {} for v in G['V']: d[v] = [-1] * k o[v] = [[]] * k d[s] = [0] * k return d, o def anti_relax(u,v,w,i,d,k,o): if d[v][i] < d[u][i-1] + w[(u,v)] * (k-i): d[v][i] = d[u][i-1] + w[(u,v)] * (k-i) o[v][i] = o[u][i-1] + [u] def find_path(G,s,k): d,o = Init(G,s,k) for i in range(k): di = deepcopy(d) for (u,v) in G['E']: if d[u][i-1] > -1 and not (u[:2] == v[:2] and v in o[u][i-1]): anti_relax(u,v,G['w'],i,di,k,o) d = deepcopy(di) return max(map(max,d.values())) def Init_double(G,s,k): d = {} o = {} for v in G['V']: d[v] = [-1] * k o[v] = [[]] * k d[s] = [0] * k return d, o def anti_relax_double(u,v,w,i,d,k,o): if d[v][i] < d[u][i-1] + w[(u,v)] * (k-i): d[v][i] = d[u][i-1] + w[(u,v)] * (k-i) o[v][i] = o[u][i-1] + [u] def find_double_path(G,s,k): d,o = Init_double(G,s,k) for i in range(k): di = deepcopy(d) for (u,v) in G['E']: if d[u][i-1] > -1 and not (u[:2] == v[:2] and v in o[u][i-1]): anti_relax_double(u,v,G['w'],i,di,k,o) for (u,v) in G['E']: if d[u][i-1] > -1 and not (u[:2] == v[:2] and (v in o[u][i-1] or v in o[u][i])): anti_relax_double(u,v,G['w'],i,di,k,o) d = deepcopy(di) return max(map(max,d.values())) if __name__ == '__main__': [parse(line.strip('\n')) for line in open(sys.argv[1])] m = find_path(VALVES,'AAC',29) # start (s): AA, length (k): 30, # challenge 1 res1 = str(m) print("challenge 1:" + "\n" + res1 + "\n") # challenge 2 m = find_double_path(VALVES,'AAC',25) # missing: magic! print(m) res2 = "" print("challenge 2:" + "\n" + res2 + "\n")