Files
aoc-2022-ocaml/src/day3.ml
T
2023-10-09 14:14:13 -07:00

58 lines
1.5 KiB
OCaml

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 |}]
;;