@@ -21,20 +21,83 @@ def get_print_instructions():
2121 return ordering , updates
2222
2323
24+ def is_update_ordered (update , ordering ):
25+ for i in range (len (update )):
26+ for j in range (i + 1 , len (update )):
27+ page1 = update [i ]
28+ page2 = update [j ]
29+ if page2 in ordering and page1 in ordering [page2 ]:
30+ return False
31+ return True
32+
33+
34+ def topological_sort (update , ordering ):
35+ """
36+ Performs a topological sort on the given update based on the ordering rules.
37+
38+ Args:
39+ update: A list of page numbers in the update.
40+ ordering: A dictionary representing the ordering rules.
41+
42+ Returns:
43+ A list of page numbers in the correct order, or None if a cycle is detected.
44+ """
45+ relevant_rules = defaultdict (list )
46+ in_degree = defaultdict (int )
47+ for before , after_list in ordering .items ():
48+ if before in update :
49+ for after in after_list :
50+ if after in update :
51+ relevant_rules [before ].append (after )
52+ in_degree [after ] += 1
53+
54+ for node in update :
55+ if node not in in_degree :
56+ in_degree [node ] = 0
57+
58+ queue = [node for node in update if in_degree [node ] == 0 ]
59+ sorted_list = []
60+
61+ while queue :
62+ node = queue .pop (0 )
63+ sorted_list .append (node )
64+
65+ for neighbor in relevant_rules .get (node , []):
66+ in_degree [neighbor ] -= 1
67+ if in_degree [neighbor ] == 0 :
68+ queue .append (neighbor )
69+
70+ if len (sorted_list ) != len (update ):
71+ # print('cycle detected')
72+ return None
73+
74+ return sorted_list
75+
76+
2477def part1 ():
2578 ordering , updates = get_print_instructions ()
26- count = 0
79+ total_middle_page = 0
2780
2881 for update in updates :
29- # for each update
30- # check that pages follow the rules
31- pass
82+ if is_update_ordered ( update , ordering ):
83+ middle_index = len ( update ) // 2
84+ total_middle_page += update [ middle_index ]
3285
33- print ('Part 1:' , count )
86+ print ('Part 1:' , total_middle_page )
3487
3588
3689def part2 ():
37- print ('Part 2:' )
90+ ordering , updates = get_print_instructions ()
91+ total_middle_page = 0
92+
93+ for update in updates :
94+ if not is_update_ordered (update , ordering ):
95+ sorted_update = topological_sort (update , ordering )
96+ if sorted_update :
97+ middle_index = len (sorted_update ) // 2
98+ total_middle_page += sorted_update [middle_index ]
99+
100+ print ('Part 2:' , total_middle_page )
38101
39102
40103if __name__ == '__main__' :
0 commit comments