diff --git a/lib/problems/problem_2023_01.ml b/lib/problems/problem_2023_01.ml new file mode 100644 index 0000000..a271905 --- /dev/null +++ b/lib/problems/problem_2023_01.ml @@ -0,0 +1,78 @@ +let year = 2023 +let day = 1 + +module Part_1 = struct + let run (input : string) : (string, string) result = + let string_to_digits s = + String.to_seq s |> Seq.map Char.escaped |> Seq.map int_of_string_opt + |> Seq.flat_map Option.to_seq |> Seq.map Int.to_string |> List.of_seq + in + let rec concat_digits = function + | [] -> 0 + | [ x ] -> int_of_string (x ^ x) + | [ first; last ] -> int_of_string (first ^ last) + | first :: _ :: xs -> concat_digits (first :: xs) + in + let result = + String.split_on_char '\n' input + |> List.map string_to_digits |> List.map concat_digits + |> List.fold_left ( + ) 0 |> Int.to_string + in + Ok result +end + +module Part_2 = struct + let run (input : string) : (string, string) result = + let word_to_digit_list = + [ + ("one", "1"); + ("two", "2"); + ("three", "3"); + ("four", "4"); + ("five", "5"); + ("six", "6"); + ("seven", "7"); + ("eight", "8"); + ("nine", "9"); + ("1", "1"); + ("2", "2"); + ("3", "3"); + ("4", "4"); + ("5", "5"); + ("6", "6"); + ("7", "7"); + ("8", "8"); + ("9", "9"); + ] + in + let rec find_first_digit string = + match + List.find_opt + (fun (word, _) -> String.starts_with ~prefix:word string) + word_to_digit_list + with + | Some (_, digit) -> digit + | None -> + find_first_digit (String.sub string 1 (String.length string - 1)) + in + let rec find_last_digit string = + match + List.find_opt + (fun (word, _) -> String.ends_with ~suffix:word string) + word_to_digit_list + with + | Some (_, digit) -> digit + | None -> find_last_digit (String.sub string 0 (String.length string - 1)) + in + let concat_digits s = + let first = find_first_digit s in + let last = find_last_digit s in + int_of_string (first ^ last) + in + let result = + input |> String.split_on_char '\n' + |> List.filter (fun s -> String.length s > 0) + |> List.map concat_digits |> List.fold_left ( + ) 0 |> Int.to_string + in + Ok result +end