from collections import deque START = 'svr' END = 'out' def dfs_sort(graph): visited = set() order = deque() def dfs_helper(node): visited.add(node) for v in graph.get(node, []): if v not in visited: dfs_helper(v) order.appendleft(node) dfs_helper(START) return order def dp(graph, order, start_i, end_is): dp = {node: 0 for node in graph} dp[start_i] = 1 for node in order: for neighbor in graph[node]: dp[neighbor] += dp[node] return [dp[end_i] for end_i in end_is] with open('input.txt', 'r') as file: lines = file.readlines() graph = {} for line in lines: line = line.strip() nodes = line.split() node = nodes[0].rstrip(':') edges = nodes[1:] graph[node] = edges graph[END] = [] topological_order = dfs_sort(graph) print(topological_order) pruned_graph = {node: graph[node] for node in topological_order if node in graph} # Path combinations: svr->fft->dac->out and svr->dac->fft->out svr_fft, svr_dac = dp(pruned_graph, topological_order, START, ['fft', 'dac']) fft_out, fft_dac = dp(pruned_graph, topological_order, 'fft', [END, 'dac']) dac_fft, dac_out = dp(pruned_graph, topological_order, 'dac', ['fft', END]) result = (svr_fft * fft_dac * dac_out) + (svr_dac * dac_fft * fft_out) print(result)