@@ -9,7 +9,13 @@ def part_one(input)
99 end
1010
1111 def part_two ( input )
12- 0
12+ parse_input ( input )
13+
14+ @updates
15+ . reject { |update | correct_order? ( update ) }
16+ . map { |update | reorder ( update ) }
17+ . map { |result | result [ result . size / 2 ] }
18+ . sum
1319 end
1420
1521 def correct_order? ( update )
@@ -18,6 +24,14 @@ def correct_order?(update)
1824 end
1925 end
2026
27+ def reorder ( update )
28+ @relevant_order = @order
29+ . select { |order | update . include? ( order [ 0 ] ) && update . include? ( order [ 1 ] ) }
30+
31+ re = Reorder . new ( @relevant_order )
32+ re . reorder_update ( update )
33+ end
34+
2135 def parse_input ( input )
2236 lines = input . split ( "\n " )
2337 split_idx = lines . index ( '' )
@@ -26,3 +40,44 @@ def parse_input(input)
2640 @updates = lines [ split_idx + 1 ..-1 ] . map { |line | line . split ( ',' ) . map ( &:to_i ) }
2741 end
2842end
43+
44+ class Reorder
45+ def initialize ( relevant_order )
46+ @relevant_order = relevant_order
47+ end
48+
49+ def reorder_update ( update )
50+ graph = build_graph ( @relevant_order )
51+ sorted_order = topological_sort ( graph )
52+ update . sort_by { |num | sorted_order . index ( num ) }
53+ end
54+
55+ private
56+
57+ def build_graph ( relevant_order )
58+ graph = Hash . new { |hash , key | hash [ key ] = [ ] }
59+ relevant_order . each do |before , after |
60+ graph [ before ] << after
61+ end
62+ graph
63+ end
64+
65+ def topological_sort ( graph )
66+ visited = { }
67+ stack = [ ]
68+
69+ graph . keys . each do |node |
70+ topological_sort_util ( node , visited , stack , graph ) unless visited [ node ]
71+ end
72+
73+ stack . reverse
74+ end
75+
76+ def topological_sort_util ( node , visited , stack , graph )
77+ visited [ node ] = true
78+ graph [ node ] . each do |neighbor |
79+ topological_sort_util ( neighbor , visited , stack , graph ) unless visited [ neighbor ]
80+ end
81+ stack << node
82+ end
83+ end
0 commit comments