Setup Scala
This commit is contained in:
parent
8dec7591dd
commit
13a8e74189
37 changed files with 290 additions and 187 deletions
12
ocaml/lib/problems/dune
Normal file
12
ocaml/lib/problems/dune
Normal 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))
|
||||
4
ocaml/lib/problems/generator/dune
Normal file
4
ocaml/lib/problems/generator/dune
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
(executable
|
||||
(name gen)
|
||||
(modules gen)
|
||||
(libraries fmt))
|
||||
21
ocaml/lib/problems/generator/gen.ml
Normal file
21
ocaml/lib/problems/generator/gen.ml
Normal 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
|
||||
78
ocaml/lib/problems/problem_2023_01.ml
Normal file
78
ocaml/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
|
||||
46
ocaml/lib/problems/problem_2023_02.ml
Normal file
46
ocaml/lib/problems/problem_2023_02.ml
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue