-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path25.py
46 lines (40 loc) · 1.33 KB
/
25.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import collections
import random
import re
lines = [line.strip() for line in open('25.txt')]
def canonical_edge(src, dst):
return tuple(sorted((src, dst)))
G = collections.defaultdict(set)
VALID_EDGES = set()
for line in lines:
parts = re.findall(r'\w+', line)
src, *dsts = parts
for dst in dsts:
G[src].add(dst)
G[dst].add(src)
VALID_EDGES.add(canonical_edge(src, dst))
# Pick two nodes at random and try to find a shortest path between them 4 times
# in a row, while using different edges each time. This is only possible if the
# nodes are in different components.
nodes = list(G)
while True:
valid_edges = set(VALID_EDGES)
src, dst = random.sample(nodes, 2)
for _ in range(4):
parent = {}
Q = [src]
for node in Q:
if node == dst:
while node != src:
prev_node = parent[node]
valid_edges.remove(canonical_edge(node, prev_node))
node = prev_node
break
for next_node in G[node]:
if canonical_edge(node, next_node) not in valid_edges or next_node in parent:
continue
parent[next_node] = node
Q.append(next_node)
else:
print(len(parent)*(len(G)-len(parent)))
exit(0)