Browse Source

Day 5 part 2 solution

AbdoFizzy 5 months ago
parent
commit
a7a8903781
2 changed files with 71 additions and 1 deletions
  1. 70 0
      5/solve_2.ml
  2. 1 1
      README.md

+ 70 - 0
5/solve_2.ml

@@ -0,0 +1,70 @@
+open Stdio
+open Str
+
+let read_input =
+  let rec aux rules updates= 
+    let line = In_channel.input_line In_channel.stdin in
+    match line with 
+    | None -> rules, updates
+    | Some x -> if (Str.string_match (regexp {|[0-9]+|[0-9]+|}) x 0) then
+                  let z = (List.map int_of_string (Str.split (regexp {|||}) x)) in
+                  aux ((List.nth z 0, List.nth z 1)::rules) updates else 
+                (if (Str.string_match (regexp {|[0-9]+\|,|}) x 0) then 
+                  aux rules ((List.map int_of_string (Str.split (regexp {|,|}) x))::updates) else aux rules updates)
+  in
+  aux [] []
+;;
+
+let rules_graph = (fst read_input)
+let updates = (snd read_input)
+
+let neighbors a = 
+  let aux g a =
+    let edge l (b, c) = if b = a then (c,'a') :: l
+                        else if c = a then (b,'b') :: l
+                        else l in
+    List.fold_left edge [] g in
+  aux rules_graph a
+;;
+
+let rec get_order nei = function
+| (n,o)::tl -> if (nei == n) then o else get_order nei tl
+| [] -> 'e'
+;;
+
+let rec is_page_ordered neighbors_p = function
+| [] -> true
+| hd :: tl -> if ((get_order hd neighbors_p) == 'a') then 
+                is_page_ordered neighbors_p tl else false
+;;   
+
+let get_middle_page u = let u_len = List.length u in List.nth u (u_len/2);;
+
+let sort u =
+  let rec aux sorted_u u visited = (match visited with
+  | [] -> sorted_u
+  | hd::tl -> let taint_order = List.map (fun x -> (x, get_order x (neighbors hd))) sorted_u in
+              let correct_pages = (List.map fst (List.filter (fun x -> (snd x) == 'a') taint_order)) in
+              let uncorrect_pages = (List.map fst (List.filter (fun x -> (snd x) != 'a') taint_order)) in
+              aux (uncorrect_pages@correct_pages) u tl)
+  in
+  aux u u u;;
+
+let solve =
+  let rec is_valid_update u = 
+    match u with
+    | hd :: tl -> 
+      (let hd_neighbors = neighbors hd in
+        if (is_page_ordered hd_neighbors tl) then (is_valid_update tl) else false
+      )
+    | [] -> true
+  in
+  let rec aux accum = function
+  | [] -> accum
+  | hd::tl -> if (is_valid_update hd) then aux accum tl
+                                      else aux (accum + get_middle_page (sort hd)) tl in
+  aux 0 updates
+;;
+
+
+let () = printf "Total: %d\n" solve

+ 1 - 1
README.md

@@ -46,7 +46,7 @@ replace `<part_number>` with 1 for Part 1 or 2 for Part 2
 | 2   | ✅     | ✅     |
 | 3   | ✅     | ✅     |
 | 4   | ✅     | ✅     |
-| 5   | ✅     |      |
+| 5   | ✅     |      |
 | 6   | ⬜     | ⬜     |
 | 7   | ⬜     | ⬜     |
 | 8   | ⬜     | ⬜     |