Day 1
This commit is contained in:
parent
de6ee1b2df
commit
21705e3ebe
1 changed files with 78 additions and 0 deletions
78
lib/problems/problem_2023_01.ml
Normal file
78
lib/problems/problem_2023_01.ml
Normal file
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue