tighten up day 13
List.compare is neat!
This commit is contained in:
parent
fa8970b0de
commit
06f695b34c
58
src/day13.ml
58
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 |}]
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user