open Containers module CharSet = Set.Make (Char) let set_of_string string = CharSet.of_list (String.to_list string) let priority char = match char with | 'a' .. 'z' -> 1 + Char.compare char 'a' | 'A' .. 'Z' -> 27 + Char.compare char 'A' | _ -> failwith @@ Printf.sprintf "'%c' is not a valid item" char ;; let part1 () = let lines = Utils.lines_of_input 3 in List.fold_left (fun acc line -> let half_len = String.length line / 2 in let first, second = Pair.map_same set_of_string (String.take_drop half_len line) in let item = match CharSet.elements @@ CharSet.inter first second with | [ item ] -> item | _ -> failwith "first and second half of each line should only have 1 intersection" in acc + priority item) 0 lines ;; (* shout out https://doc.sherlocode.com/ for helping me find Containers and its List.chunks and List.reduce functions *) let part2 () = let lines = Utils.lines_of_input 3 in let groups = List.chunks 3 (List.map set_of_string lines) in List.fold_left (fun acc group -> let item = match CharSet.elements @@ List.reduce_exn CharSet.inter group with | [ item ] -> item | _ -> failwith "each group of 3 lines should only have 1 intersection" in acc + priority item) 0 groups ;; let%expect_test "Day 3.1" = Printf.printf "%d" @@ part1 (); [%expect {| 7446 |}] ;; let%expect_test "Day 3.2" = Printf.printf "%d" @@ part2 (); [%expect {| 2646 |}] ;;