diff --git a/src/holt59/aoc/2024/day5.py b/src/holt59/aoc/2024/day5.py index c895ad2..83fec39 100644 --- a/src/holt59/aoc/2024/day5.py +++ b/src/holt59/aoc/2024/day5.py @@ -1,27 +1,42 @@ import sys from collections import defaultdict -import networkx as nx - def in_correct_order(update: list[int], requirements: dict[int, set[int]]) -> bool: - for i_value, value in enumerate(update): - if any(value_2 in requirements[value] for value_2 in update[i_value:]): - return False - return True - - -def fix_order(update: list[int], requirements: dict[int, set[int]]) -> list[int]: - graph = nx.DiGraph() - graph.add_nodes_from(update) - graph.add_edges_from( - (v, k) - for k, vs in requirements.items() - for v in vs - if k in update and v in update + return all( + not any(value_2 in requirements[value] for value_2 in update[i_value:]) + for i_value, value in enumerate(update) ) - return list(nx.topological_sort(graph)) + +def fix_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().split("\n\n") @@ -40,7 +55,7 @@ answer_1 = sum( ) answer_2 = sum( - fix_order(update, requirements)[len(update) // 2] + fix_order(update, requirements, len(update) // 2 + 1)[-1] for update in updates if not in_correct_order(update, requirements) )