65 lines
1.7 KiB
Python
65 lines
1.7 KiB
Python
import sys
|
|
from collections import defaultdict
|
|
|
|
|
|
def in_correct_order(update: list[int], requirements: dict[int, set[int]]) -> bool:
|
|
return all(
|
|
not any(value_2 in requirements[value] for value_2 in update[i_value:])
|
|
for i_value, value in enumerate(update)
|
|
)
|
|
|
|
|
|
def to_correct_order(
|
|
update: list[int],
|
|
requirements: dict[int, set[int]],
|
|
max_update_length: int | None = None,
|
|
) -> list[int]:
|
|
# copy requirements to update
|
|
requirements = {
|
|
value: {predecessor for predecessor in predecessors if predecessor in update}
|
|
for value, predecessors in requirements.items()
|
|
if value in update
|
|
}
|
|
|
|
max_update_length = max_update_length or len(update)
|
|
|
|
update = []
|
|
while requirements and len(update) < max_update_length:
|
|
value = next(
|
|
value for value, predecessors in requirements.items() if not predecessors
|
|
)
|
|
|
|
update.append(value)
|
|
del requirements[value]
|
|
|
|
for predecessors in requirements.values():
|
|
if value in predecessors:
|
|
predecessors.remove(value)
|
|
|
|
return update
|
|
|
|
|
|
part1, part2 = sys.stdin.read().strip().split("\n\n")
|
|
|
|
requirements: dict[int, set[int]] = defaultdict(set)
|
|
for line in part1.splitlines():
|
|
v1, v2 = line.split("|")
|
|
requirements[int(v2)].add(int(v1))
|
|
|
|
updates = [list(map(int, line.split(","))) for line in part2.splitlines()]
|
|
|
|
answer_1 = sum(
|
|
update[len(update) // 2]
|
|
for update in updates
|
|
if in_correct_order(update, requirements)
|
|
)
|
|
|
|
answer_2 = sum(
|
|
to_correct_order(update, requirements, len(update) // 2 + 1)[-1]
|
|
for update in updates
|
|
if not in_correct_order(update, requirements)
|
|
)
|
|
|
|
print(f"answer 1 is {answer_1}")
|
|
print(f"answer 2 is {answer_2}")
|