changeset 37:fa09d8bce45a

Day 02 Part 2
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 02 Dec 2023 17:32:03 +0100
parents 326aec2bdce6
children cce3368a1897
files 2023/day02.ml
diffstat 1 files changed, 26 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/2023/day02.ml	Sat Dec 02 17:21:17 2023 +0100
+++ b/2023/day02.ml	Sat Dec 02 17:32:03 2023 +0100
@@ -2,12 +2,12 @@
 open Base
 open Core
 
+type color = Red | Green | Blue [@@deriving sexp]
+type reveal = { red : int; green : int; blue : int } [@@deriving sexp]
+type game = { id : int; reveals : reveal list } [@@deriving sexp]
+
 module Part1 = struct
   module Parser = struct
-    type color = Red | Green | Blue [@@deriving sexp]
-    type reveal = { red : int; green : int; blue : int } [@@deriving sexp]
-    type game = { id : int; reveals : reveal list } [@@deriving sexp]
-
     (* Parse a game like
        "Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red"
     *)
@@ -51,13 +51,12 @@
 
   exception Game_parse_failed of string
 
-  let process_line line =
+  let parse_line line =
     match Parser.parse_game line with
     | Ok o -> o
     | Error e -> raise (Game_parse_failed e)
 
   let check_reveal contents reveal =
-    let open Parser in
     let { red = cr; green = cg; blue = cb } = contents in
     let { red = rr; green = rg; blue = rb } = reveal in
     rr <= cr && rg <= cg && rb <= cb
@@ -67,20 +66,33 @@
     List.fold ~init:true ~f game
 
   let check_line contents line =
-    let game = process_line line in
+    let game = parse_line line in
     if check_game contents game.reveals then game.id else 0
 end
 
-let fold_lines contents =
+module Part2 = struct
+  let min_contents_fold acc rev =
+    let { red = ar; green = ag; blue = ab } = acc in
+    let { red = rr; green = rg; blue = rb } = rev in
+    Int.{ red = max ar rr; green = max ag rg; blue = max ab rb }
+
+  let min_contents =
+    List.fold ~init:{ red = 0; green = 0; blue = 0 } ~f:min_contents_fold
+
+  let power game =
+    let mc = min_contents game.reveals in
+    mc.red * mc.green * mc.blue
+end
+
+let _fold_lines1 contents =
   let f acc line = acc + Part1.check_line contents line in
   In_channel.fold_lines In_channel.stdin ~f ~init:0
 
-let _test1 () =
-  let line = Option.value_exn @@ In_channel.input_line In_channel.stdin in
-  let s = Part1.process_line line in
-  Out_channel.output_string Out_channel.stdout
-    (Sexp.to_string (Part1.Parser.sexp_of_game s))
+let fold_lines2 () =
+  let f acc line = acc + (Part2.power @@ Part1.parse_line line) in
+  In_channel.fold_lines In_channel.stdin ~f ~init:0
 
 let () =
   Out_channel.printf "%d\n"
-    (fold_lines Part1.Parser.{ red = 12; green = 13; blue = 14 })
+    (*(fold_lines1 Part1.Parser.{ red = 12; green = 13; blue = 14 })*)
+    (fold_lines2 ())