changeset 56:3175a3fe84e5

Day 09 Part 2
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 15 Dec 2023 11:08:35 +0100
parents 3aa1f3d5ee56
children 4a584287ebec
files 2023/day09.ml
diffstat 1 files changed, 24 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/2023/day09.ml	Fri Dec 15 11:03:13 2023 +0100
+++ b/2023/day09.ml	Fri Dec 15 11:08:35 2023 +0100
@@ -6,7 +6,10 @@
 
 module Parse = struct
   let maybe p = option () (p >>= fun _ -> return ())
-  let intP = take_while1 (fun c -> Char.(c = '-' || is_digit c)) >>| Int.of_string
+
+  let intP =
+    take_while1 (fun c -> Char.(c = '-' || is_digit c)) >>| Int.of_string
+
   let int_listP = skip_many (char ' ') *> sep_by1 (skip_many1 (char ' ')) intP
   let int_listsP = sep_by1 (char '\n') int_listP <* maybe (char '\n')
 
@@ -32,21 +35,36 @@
     | _ :: _ -> false
     | [] -> true
 
+  (* a very simple recursive procedure: *)
   let rec reduce_all s =
-    let last = List.last_exn s in
+    let last_elem = List.last_exn s in
     let reduced, _ = reduce1 s in
-    if all_zeros reduced then last
+    if all_zeros reduced then last_elem
     else
       let next = reduce_all (List.rev reduced) in
-      Out_channel.printf "%d / %d\n" next last;
-      next + last
+      Out_channel.printf "%d / %d\n" next last_elem;
+      next + last_elem
+
+  let process = List.map ~f:reduce_all
+end
+
+module Part2 = struct
+  (* The same as Part1.reduce_all, except we look at the first element and do a subtraction. *)
+  let rec reduce_all s =
+    let first_elem = List.hd_exn s in
+    let reduced, _ = Part1.reduce1 s in
+    if Part1.all_zeros reduced then first_elem
+    else
+      let next = reduce_all (List.rev reduced) in
+      Out_channel.printf "%d / %d\n" next first_elem;
+      first_elem - next
 
   let process = List.map ~f:reduce_all
 end
 
 let () =
   let inp = Parse.parse_input In_channel.stdin in
-  let result = Part1.process inp in
+  let result = Part2.process inp in
   let str = Sexp.to_string_hum @@ sexp_of_seq result in
   Out_channel.(
     output_string stdout str;