diff --git a/src/day13.ml b/src/day13.ml index 446062e..ad9c1ad 100644 --- a/src/day13.ml +++ b/src/day13.ml @@ -11,33 +11,25 @@ let packet_of_str line = take_while1 (function | '0' .. '9' -> true | _ -> false) - >>= fun s -> return (I (int_of_string s)) "int" + >>= fun s -> return @@ I (int_of_string s) "int" in let packet = fix (fun packet -> - let list = - char '[' *> sep_by (char ',') packet - <* char ']' - >>= fun s -> return (L s) "list" - in + let lb, rb = char '[', char ']' in + let delim = sep_by (char ',') in + let list = lb *> delim packet <* rb >>= fun p -> return @@ L p "list" in choice [ int; list ]) "packet" in Result.get_or_failwith @@ parse_string ~consume:All packet line ;; -let rec is_ordered = function - | I a, I b when a = b -> None - | I a, I b -> Some (a < b) - | (I _ as a), (L _ as b) -> is_ordered (L [ a ], b) - | (L _ as a), (I _ as b) -> is_ordered (a, L [ b ]) - | L [], L [] -> None - | L [], _ -> Some true - | _, L [] -> Some false - | L (a :: a_tl), L (b :: b_tl) -> - (match is_ordered (a, b) with - | None -> is_ordered (L a_tl, L b_tl) - | result -> result) +let rec is_ordered a b = + match a, b with + | I a, I b -> Int.compare a b + | L a, L b -> List.compare is_ordered a b + | (I _ as a), (L _ as b) -> is_ordered (L [ a ]) b + | (L _ as a), (I _ as b) -> is_ordered a (L [ b ]) ;; let%expect_test "Day 13.1" = @@ -48,14 +40,9 @@ let%expect_test "Day 13.1" = |> List.chunks 2 |> List.mapi (fun i packets -> match packets with - | [ a; b ] -> i + 1, is_ordered (a, b) - | _ -> failwith "List.chunks didnt work lol") - |> List.fold_left - (fun result item -> - match item with - | i, Some true -> result + i - | _, _ -> result) - 0 + | [ a; b ] when is_ordered a b < 0 -> i + 1 + | _ -> 0) + |> List.reduce_exn ( + ) in Printf.printf "%i" result; [%expect {| 6272 |}] @@ -65,20 +52,11 @@ let%expect_test "Day 13.2" = let result = Utils.lines_of_input 13 |> List.filter Fun.(not % String.is_empty) - |> List.append [ "[[2]]"; "[[6]]" ] - |> List.map (fun line -> line, packet_of_str line) - |> List.sort (fun (_, a) (_, b) -> - match is_ordered (a, b) with - | None -> 0 - | Some true -> -1 - | Some false -> 1) - |> List.mapi (fun i (line, _) -> i + 1, line) - |> List.fold_left - (fun result (i, line) -> - match line with - | "[[2]]" | "[[6]]" -> result * i - | _ -> result) - 1 + |> List.map (fun line -> false, packet_of_str line) + |> List.append [ true, packet_of_str "[[2]]"; true, packet_of_str "[[6]]" ] + |> List.sort (fun (_, a) (_, b) -> is_ordered a b) + |> List.mapi (fun i (is_divider, _) -> if is_divider then i + 1 else 1) + |> List.reduce_exn ( * ) in Printf.printf "%i" result; [%expect {| 22288 |}]