Setup Scala

This commit is contained in:
Paul-Henri Froidmont 2023-12-04 08:02:51 +01:00
parent 8dec7591dd
commit 13a8e74189
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
37 changed files with 290 additions and 187 deletions

12
ocaml/lib/problems/dune Normal file
View file

@ -0,0 +1,12 @@
(rule
(target all.ml)
(deps
(:problem_files
(glob_files "./problem*{[!r][!e].ml,.re}"))
(:generator generator/gen.exe))
(action
(run %{generator} %{target} %{problem_files})))
(library
(name problems)
(libraries problem import str))

View file

@ -0,0 +1,4 @@
(executable
(name gen)
(modules gen)
(libraries fmt))

View file

@ -0,0 +1,21 @@
let pp_module_name (f : Format.formatter) (module_name : string) : unit =
Fmt.pf f "(module %s: Problem.T)" module_name
let pp_file (f : Format.formatter) (module_names : string list) : unit =
Fmt.(
pf f {ocaml|let all: (module Problem.T) list = [%a]|ocaml}
(list ~sep:semi pp_module_name)
module_names)
let () =
let output_filename = Array.get Sys.argv 1 in
let filenames =
Sys.argv |> Array.to_list |> List.tl |> List.tl
|> List.map
(String.mapi (fun i c -> if i = 0 then Char.uppercase_ascii c else c))
|> List.map (fun s -> String.sub s 0 (String.length s - 3))
in
let contents = Fmt.str "%a" pp_file filenames in
let c = open_out output_filename in
output_string c contents;
close_out c

View 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

View file

@ -0,0 +1,46 @@
let year = 2023
let day = 1
module Part_1 = struct
type color = Red | Blue | Green
type set = { count : int; color : color }
type game = { number : int; sets : set list }
let print_game { number ; _ } =
Printf.sprintf "%i" number
let run (input : string) : (string, string) result =
let parse_color = function
| "red" -> Red
| "blue" -> Blue
| "green" -> Green
| _ -> assert false
in
let parse_set str =
match String.split_on_char ',' str with
| [ number; color ] ->
{ count = int_of_string number; color = parse_color color }
| _ -> assert false
in
let parse_sets str = String.split_on_char ';' str |> List.map parse_set in
let parse_game_number str =
match String.trim str |> String.split_on_char ' ' with
| [ _; number ] -> int_of_string number
| _ -> assert false
in
let parse_line str =
match String.split_on_char ':' str with
| [ prefix; suffix ] ->
{ number = parse_game_number prefix; sets = parse_sets suffix }
| _ -> assert false
in
let (games : game list) =
input |> String.trim |> String.split_on_char '\n' |> List.map parse_line
in
Ok (List.hd games |> print_game)
end
module Part_2 = struct
let run (input : string) : (string, string) result =
Ok input
end