58 lines
1.5 KiB
OCaml
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 |}]
|
|
;;
|