2024-12-05 07:52:55 +00:00
|
|
|
import functools
|
|
|
|
|
|
|
|
def parse(file):
|
|
|
|
rules = []
|
|
|
|
for line in file:
|
|
|
|
line = line.strip()
|
|
|
|
if line == "":
|
|
|
|
break
|
|
|
|
a, _, b = line.partition('|')
|
|
|
|
rules.append((a,b))
|
|
|
|
updates = []
|
|
|
|
for line in file:
|
|
|
|
line = line.strip()
|
|
|
|
updates.append(line.split(','))
|
|
|
|
return rules, updates
|
|
|
|
|
|
|
|
def solve(file):
|
|
|
|
rules, updates = parse(file)
|
|
|
|
rules = set(rules)
|
|
|
|
def isvalid(pages):
|
|
|
|
for i in range(len(pages)):
|
|
|
|
p = pages[i]
|
|
|
|
for g in pages[i+1:]:
|
|
|
|
if (g,p) in rules:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2024-12-05 08:11:04 +00:00
|
|
|
# part 1
|
2024-12-05 07:52:55 +00:00
|
|
|
t = 0
|
|
|
|
invalid = []
|
|
|
|
for pages in updates:
|
|
|
|
if isvalid(pages):
|
|
|
|
print(pages)
|
|
|
|
t += int(pages[len(pages)//2])
|
|
|
|
else:
|
|
|
|
invalid.append(pages)
|
|
|
|
print(t)
|
|
|
|
|
2024-12-05 08:11:04 +00:00
|
|
|
# part 2: select applicable rules and form a graph
|
|
|
|
# find the root node
|
|
|
|
# do a topological sort by doing a DFS of the graph
|
2024-12-05 08:07:02 +00:00
|
|
|
t = 0
|
|
|
|
for pages in invalid:
|
2024-12-05 08:11:04 +00:00
|
|
|
# select rules
|
2024-12-05 08:07:02 +00:00
|
|
|
rules2 = [(p,g) for p,g in rules if p in pages and g in pages]
|
|
|
|
#print(pages, rules2)
|
2024-12-05 08:11:04 +00:00
|
|
|
|
|
|
|
# find root node
|
2024-12-05 08:07:02 +00:00
|
|
|
S = set(p for p,g in rules2)
|
|
|
|
E = set(g for p,g in rules2)
|
|
|
|
top = next(iter(S-E))
|
2024-12-05 08:11:04 +00:00
|
|
|
|
2024-12-05 08:07:02 +00:00
|
|
|
# topological sort
|
|
|
|
l = []
|
|
|
|
seen = set()
|
|
|
|
def visit(node):
|
|
|
|
if node in seen: return
|
|
|
|
seen.add(node)
|
|
|
|
for p,g in rules2:
|
|
|
|
if p == node and g not in seen:
|
|
|
|
visit(g)
|
|
|
|
l.append(node)
|
|
|
|
visit(top)
|
|
|
|
l.reverse()
|
2024-12-05 08:11:04 +00:00
|
|
|
|
|
|
|
# sanity check
|
|
|
|
assert len(l) == len(pages)
|
|
|
|
assert isvalid(l)
|
2024-12-05 08:07:02 +00:00
|
|
|
print(l)
|
2024-12-05 08:11:04 +00:00
|
|
|
|
|
|
|
# add middle number to total
|
2024-12-05 08:07:02 +00:00
|
|
|
t += int(l[len(l)//2])
|
|
|
|
print(t)
|
|
|
|
|
2024-12-05 07:52:55 +00:00
|
|
|
|
|
|
|
solve(open("sample1.in"))
|
|
|
|
solve(open("input"))
|