put packet in a inline module cuz why not

This commit is contained in:
ryan committed 2023-10-31 10:08:20 -07:00
1 parent 06f695b34c
commit 8fe7e77b52
1 file changed
+48 -51
+48 -51
View File
@@ -1,63 +1,60 @@
open Containers open Containers
type packet = module Packet = struct
| I of int type t =
| L of packet list | I of int
[@@deriving show { with_path = false }] | L of t list
[@@deriving show { with_path = false }]
let packet_of_str line = let of_str line =
let open Angstrom in let open Angstrom in
let int = let int =
take_while1 (function take_while1 (function
| '0' .. '9' -> true | '0' .. '9' -> true
| _ -> false) | _ -> false)
>>= fun s -> return @@ I (int_of_string s) <?> "int" >>= fun s -> return @@ I (int_of_string s) <?> "int"
in in
let packet = let packet =
fix (fun packet -> fix (fun packet ->
let lb, rb = char '[', char ']' in let lb, delimited, rb = char '[', sep_by (char ','), char ']' in
let delim = sep_by (char ',') in let list = lb *> delimited packet <* rb >>= fun p -> return @@ L p <?> "list" in
let list = lb *> delim packet <* rb >>= fun p -> return @@ L p <?> "list" in choice [ int; list ])
choice [ int; list ]) <?> "packet"
<?> "packet" in
in Result.get_or_failwith @@ parse_string ~consume:All packet line
Result.get_or_failwith @@ parse_string ~consume:All packet line ;;
;;
let rec is_ordered a b = let rec compare a b =
match a, b with match a, b with
| I a, I b -> Int.compare a b | I a, I b -> Int.compare a b
| L a, L b -> List.compare is_ordered a b | L a, L b -> List.compare compare a b
| (I _ as a), (L _ as b) -> is_ordered (L [ a ]) b | (I _ as a), (L _ as b) -> compare (L [ a ]) b
| (L _ as a), (I _ as b) -> is_ordered a (L [ b ]) | (L _ as a), (I _ as b) -> compare a (L [ b ])
;; ;;
end
let%expect_test "Day 13.1" = let%expect_test "Day 13.1" =
let result = Utils.lines_of_input 13
Utils.lines_of_input 13 |> List.filter Fun.(not % String.is_empty)
|> List.filter Fun.(not % String.is_empty) |> List.map Packet.of_str
|> List.map packet_of_str |> List.chunks 2
|> List.chunks 2 |> List.mapi (fun i packets ->
|> List.mapi (fun i packets -> match packets with
match packets with | [ a; b ] when Packet.compare a b < 0 -> i + 1
| [ a; b ] when is_ordered a b < 0 -> i + 1 | _ -> 0)
| _ -> 0) |> List.reduce_exn ( + )
|> List.reduce_exn ( + ) |> print_int;
in
Printf.printf "%i" result;
[%expect {| 6272 |}] [%expect {| 6272 |}]
;; ;;
let%expect_test "Day 13.2" = let%expect_test "Day 13.2" =
let result = Utils.lines_of_input 13
Utils.lines_of_input 13 |> List.filter Fun.(not % String.is_empty)
|> List.filter Fun.(not % String.is_empty) |> List.map (fun line -> false, Packet.of_str line)
|> List.map (fun line -> false, packet_of_str line) |> List.append [ true, Packet.of_str "[[2]]"; true, Packet.of_str "[[6]]" ]
|> List.append [ true, packet_of_str "[[2]]"; true, packet_of_str "[[6]]" ] |> List.sort (fun (_, a) (_, b) -> Packet.compare a b)
|> List.sort (fun (_, a) (_, b) -> is_ordered a b) |> List.mapi (fun i (is_divider, _) -> if is_divider then i + 1 else 1)
|> List.mapi (fun i (is_divider, _) -> if is_divider then i + 1 else 1) |> List.reduce_exn ( * )
|> List.reduce_exn ( * ) |> print_int;
in
Printf.printf "%i" result;
[%expect {| 22288 |}] [%expect {| 22288 |}]
;; ;;