rearrange some stuff

This commit is contained in:
Rhiannon Morris 2020-12-03 15:11:29 +01:00
parent 5c59d80e00
commit 6ac8be6984
10 changed files with 84 additions and 51 deletions

View File

@ -5,4 +5,4 @@ let days = [|Day1.main; Day2.main; Day3.main|]
let _ =
match Array.to_list Sys.argv with
| _exename :: day :: args -> days.(int_of_string day - 1) args
| _ -> Usage.exit "<day> args..."
| _ -> Misc.usage "<day> args..."

32
day1.ml
View File

@ -1,13 +1,4 @@
module IntSet = struct
include Set.Make(Int)
let exists_opt (type a) (f: int -> a option) (set: t): a option =
let exception Found of a in
let f' x = Option.iter (fun x -> raise (Found x)) (f x) in
match iter f' set with
| exception Found x -> Some x
| _ -> None
end
module IntSet = Set_ext.Make(Int)
let read_ints =
Bracket.infile_lines ~line:int_of_string ~of_seq:IntSet.of_seq
@ -23,31 +14,18 @@ let rec find ?(target=2020) ~n set =
Option.map (List.cons x) (find ~target:(target - x) ~n:(n - 1) set) in
IntSet.exists_opt joined set
let print_result xs =
let res = List.fold_left ( * ) 1 xs in
let rec print_prod fmt = function
| [] -> Format.pp_print_text fmt "{}"
| [x] -> Format.fprintf fmt "%d" x
| x::xs -> Format.fprintf fmt "%d * %a" x print_prod xs in
Format.printf "%a = %d\n" print_prod xs res
let main' n input =
match find ~n (read_ints input) with
| Some xs -> print_result xs
| Some xs -> Misc.print_prod xs
| None -> raise Not_found
let mains = [|main' 2; main' 3|]
let main = function
| [part; input] -> mains.(int_of_string part - 1) input
| _ -> Usage.exit_default 1
let main = Misc.main 1 [|main' 2; main' 3|]
let%expect_test "part 1" =
mains.(0) "../../data/day1"; (* is this always the right path??? *)
main' 2 "../../data/day1"; (* is this always the right path??? *)
[%expect{| 534 * 1486 = 793524 |}]
let%expect_test "part 2" =
mains.(1) "../../data/day1";
main' 3 "../../data/day1";
[%expect{| 71 * 686 * 1263 = 61515678 |}]

10
day2.ml
View File

@ -26,17 +26,13 @@ let main' ok input =
Bracket.infile_iter_lines input ~line:parse_line ~iter:check;
Printf.printf "%d out of %d ok\n" !count_ok !count_all
let mains = [|main' ok1; main' ok2|]
let main = function
| [part; input] -> mains.(int_of_string part - 1) input
| _ -> Usage.exit_default 2
let main = Misc.main 2 [|main' ok1; main' ok2|]
let%expect_test "part 1" =
mains.(0) "../../data/day2";
main' ok1 "../../data/day2";
[%expect{| 607 out of 1000 ok |}]
let%expect_test "part 2" =
mains.(1) "../../data/day2";
main' ok2 "../../data/day2";
[%expect{| 321 out of 1000 ok |}]

13
day3.ml
View File

@ -36,19 +36,14 @@ let main1 input =
let main2 input =
let map = read_file input in
let prod = List.fold_left ( * ) 1
Misc.print_prod
[count_trees map;
count_trees map ~step_y:3;
count_trees map ~step_y:5;
count_trees map ~step_y:7;
count_trees map ~step_x:2] in
Format.printf "product: %d\n" prod
count_trees map ~step_x:2]
let mains = [|main1; main2|]
let main = function
| [part; input] -> mains.(int_of_string part - 1) input
| _ -> Usage.exit_default 3
let main = Misc.main 3 [|main1; main2|]
let%expect_test _ =
main1 "../../data/day3";
@ -56,4 +51,4 @@ let%expect_test _ =
let%expect_test _ =
main2 "../../data/day3";
[%expect{| product: 9406609920 |}]
[%expect{| 90 * 244 * 97 * 92 * 48 = 9406609920 |}]

2
dune
View File

@ -7,4 +7,4 @@
(public_name aoc2020)
(inline_tests)
(modules (:standard \ aoc2020))
(preprocess (pps ppx_expect)))
(preprocess (pps ppx_deriving.std ppx_expect)))

31
misc.ml Normal file
View File

@ -0,0 +1,31 @@
let usage args =
let err = Format.sprintf "usage: %s %s" Sys.argv.(0) args in
print_endline err;
exit 1
let usage_default day = usage (string_of_int day ^ " <part> <infile>")
let main day mains = function
| [part; input] -> mains.(int_of_string part - 1) input
| _ -> usage_default day
type 'a monoid =
{id: 'a;
op: 'a -> 'a -> 'a;
op_name: string;
pp: Format.formatter -> 'a -> unit}
let mult = {id = 1; op = ( * ); op_name = "*"; pp = Format.pp_print_int}
let add = {id = 0; op = ( + ); op_name = "+"; pp = Format.pp_print_int}
let print_fold mon xs =
let res = List.fold_left mon.op mon.id xs in
let rec go fmt = function
| [] -> Format.fprintf fmt "%a" mon.pp mon.id
| [x] -> Format.fprintf fmt "%a" mon.pp x
| x::xs -> Format.fprintf fmt "%a * %a" mon.pp x go xs in
Format.printf "%a = %a\n" go xs mon.pp res
let print_prod = print_fold mult
let print_sum = print_fold add

16
misc.mli Normal file
View File

@ -0,0 +1,16 @@
val usage: string -> 'a
val usage_default: int -> 'a
val main: int -> (string -> unit) array -> string list -> unit
type 'a monoid =
{id: 'a;
op: 'a -> 'a -> 'a;
op_name: string;
pp: Format.formatter -> 'a -> unit}
val mult: int monoid
val add: int monoid
val print_fold: 'a monoid -> 'a list -> unit
val print_prod: int list -> unit
val print_sum: int list -> unit

15
set_ext.ml Normal file
View File

@ -0,0 +1,15 @@
module type S = sig
include Set.S
val exists_opt: (elt -> 'a option) -> t -> 'a option
end
module Make(Elt: Set.OrderedType) = struct
include Set.Make(Elt)
let exists_opt (type a) (f: elt -> a option) set =
let exception Found of a in
let f' x = Option.iter (fun x -> raise (Found x)) (f x) in
match iter f' set with
| exception Found x -> Some x
| _ -> None
end

8
set_ext.mli Normal file
View File

@ -0,0 +1,8 @@
module type S = sig
include Set.S
val exists_opt: (elt -> 'a option) -> t -> 'a option
end
module Make(Elt: Set.OrderedType): S
with type elt = Elt.t
and type t = Set.Make(Elt).t

View File

@ -1,6 +0,0 @@
let exit args =
let err = Format.sprintf "usage: %s %s" Sys.argv.(0) args in
print_endline err;
exit 1
let exit_default day = exit (string_of_int day ^ " <part> <infile>")