2025-12-11 21:13:19 +00:00

74 lines
1.7 KiB
Python

import heapq
def solve(input):
G = {}
V = []
for line in open(input):
parts = line.split()
v = parts.pop(0).strip(':')
V.append(v)
G[v] = parts
sinks = [e for edges in G.values() for e in edges if e not in V]
V += sinks
for v in sinks:
G[v] = []
# reversed graph
R = {}
for v, E in G.items():
for e in E:
R.setdefault(e, []).append(v)
# topological sort
# T is an order of vertices such that each vertex is
# listed _after_ all the vertices connected to its incoming edges.
T = []
seen = set()
def visit(v):
if v not in seen:
seen.add(v)
for e in R.get(v,()):
visit(e)
T.append(v)
visit('out')
#T.reverse()
#print(T)
def paths(start,end):
Q = [(0,start)]
seen = set()
paths = {v:0 for v in V}
paths[start] = 1
for v in T:
if v in seen:
continue
seen.add(v)
for e in G[v]:
paths[e] += paths[v]
#print(paths)
return paths[end]
if 'you' in G:
# Part 1:
# find all paths from you -> out
print(paths('you', 'out'))
if 'svr' in G:
# Part 2: find all paths that pass through
# svr -> fft -> dac -> out, or
# svr -> dac -> fft -> out.
sf = paths('svr', 'fft')
sd = paths('svr', 'dac')
fd = paths('fft', 'dac')
df = paths('dac', 'fft')
do = paths('dac', 'out')
fo = paths('fft', 'out')
print(sf*fd*do + sd*df*fo)
solve("sample")
solve("sample2")
solve("input")