Watch
1
0
Fork
You've already forked advent-of-code
0
advent-of-code/2024/src/day05.py
2024-12-04 22:27:10 -08:00

71 lines
1.4 KiB
Python

import os
from collections import defaultdict
from dataclasses import dataclass
from functools import cmp_to_key
def relpath(path: str) -> str:
return os.path.join(os.path.dirname(__file__), path)
with open(relpath("../input/day05.txt")) as f:
text = f.read()
sections = text.split("\n\n")
rules = [
tuple(map(int, line.split("|")))
for line in sections[0].splitlines()
]
updates = [
tuple(map(int, line.split(",")))
for line in sections[1].splitlines()
]
@dataclass
class Constraint:
before: set[int]
after: set[int]
constraints = defaultdict(lambda: Constraint(before=set(), after=set()))
for (x, y) in rules:
constraints[x].after.add(y)
constraints[y].before.add(x)
def is_valid(update):
for (x, y) in zip(update[:-1], update[1:]):
if x not in constraints or y in constraints[x].after:
continue
return False
return True
def part1():
return sum(
update[int(len(update)) // 2]
for update in updates
if is_valid(update)
)
def part2():
def compare(x, y):
if y in constraints[x].after:
return +1
if y in constraints[x].before:
return -1
return 0
return sum(
sorted(update, key=cmp_to_key(compare))[int(len(update)) // 2]
for update in updates
if not is_valid(update)
)
print(part1())
print(part2())