diff --git a/2021/day-10/common.ml b/2021/day-10/common.ml index da4b090..37c4da3 100644 --- a/2021/day-10/common.ml +++ b/2021/day-10/common.ml @@ -19,3 +19,36 @@ let is_pair o c = | ('{', '}') -> true | ('<', '>') -> true | (_, _) -> false + +let rec rem_score stack points = + let score ch = + match ch with + | '(' -> 1 + | '[' -> 2 + | '{' -> 3 + | '<' -> 4 + | _ -> 0 + in + + match stack with + | [] -> points + | x :: xs -> rem_score xs (points * 5 + (score x)) + +let err_score ch = + match ch with + | ')' -> 3 + | ']' -> 57 + | '}' -> 1197 + | '>' -> 25137 + | _ -> 0 + + +let rec scores line stack error_score = + match (line, stack) with + | ([], _) -> (error_score, rem_score stack 0) + | (x :: xs, y :: ys) when is_closing x -> + if is_pair y x + then scores xs ys error_score + else scores xs ys (error_score + err_score x) + | (x :: xs, _) -> + scores xs (x :: stack) error_score diff --git a/2021/day-10/part_one.ml b/2021/day-10/part_one.ml index 408fd34..39bef24 100644 --- a/2021/day-10/part_one.ml +++ b/2021/day-10/part_one.ml @@ -1,28 +1,13 @@ open Common -let score ch = - match ch with - | ')' -> 3 - | ']' -> 57 - | '}' -> 1197 - | '>' -> 25137 - | _ -> 0 - -let rec count_errors line stack errors = - match (line, stack) with - | ([], _) -> errors - | (x :: xs, y :: ys) when is_closing x -> - if is_pair y x - then count_errors xs ys errors - else count_errors xs ys (errors + score x) - | (x :: xs, _) -> - count_errors xs (x :: stack) errors - let () = let path = Sys.argv.(1) in read_file path - |> List.map (fun cs -> count_errors cs [] 0) + |> List.map (fun cs -> + match scores cs [] 0 with + | (e, _) -> e + ) |> List.fold_left (+) 0 |> print_int; diff --git a/2021/day-10/part_two.ml b/2021/day-10/part_two.ml index e83e72f..b652360 100644 --- a/2021/day-10/part_two.ml +++ b/2021/day-10/part_two.ml @@ -1,33 +1,14 @@ open Common -let score ch = - match ch with - | '(' -> 1 - | '[' -> 2 - | '{' -> 3 - | '<' -> 4 - | _ -> 0 - -let rec score_remaining stack points = - match stack with - | [] -> points - | x :: xs -> score_remaining xs (points * 5 + (score x)) - -let rec score_closing line stack = - match (line, stack) with - | ([], _) -> Some (score_remaining stack 0) - | (x :: xs, y :: ys) when is_closing x -> - if is_pair y x - then score_closing xs ys - else None - | (x :: xs, _) -> - score_closing xs (x :: stack) - let () = let path = Sys.argv.(1) in read_file path - |> List.filter_map (fun cs -> score_closing cs []) + |> List.filter_map (fun cs -> + match scores cs [] 0 with + | (0, r) -> Some(r) + | (_, _) -> None + ) |> List.sort compare |> fun lst -> List.nth lst (List.length lst / 2) |> print_int;