Compare commits
4 Commits
4eb967fd88
...
aaa031e6c6
Author | SHA1 | Date | |
---|---|---|---|
aaa031e6c6 | |||
4f963e0f98 | |||
4c9ae83184 | |||
33d7b34002 |
45
bin/day2419.ml
Normal file
45
bin/day2419.ml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
(** [towels_of_strings lst] returns a pair containing a list of available towels
|
||||||
|
and a list of patterns wanted. *)
|
||||||
|
let towels_of_strings = function
|
||||||
|
| h :: "" :: t ->
|
||||||
|
let re = Str.regexp "[, ]+" in
|
||||||
|
let h = Str.split re h in
|
||||||
|
(h, t)
|
||||||
|
| _ -> failwith "towels_of_strings"
|
||||||
|
|
||||||
|
(** [towels_of_file fname] returns the list of towels and patterns from the file
|
||||||
|
[fname]. *)
|
||||||
|
let towels_of_file fname = Aoc.strings_of_file fname |> towels_of_strings
|
||||||
|
|
||||||
|
(** Memoizing hash table shared between parts 1 and 2. *)
|
||||||
|
let memo = Hashtbl.create 1000
|
||||||
|
|
||||||
|
(** [count_hashes memo towels pattern] counts the number of ways of matching
|
||||||
|
[pattern] using [towels]. [memo] is a hashtable used for memoizing results.
|
||||||
|
*)
|
||||||
|
let rec count_matches memo towels pattern =
|
||||||
|
let pattern_len = String.length pattern in
|
||||||
|
let rec count_matched = function
|
||||||
|
| [] -> 0
|
||||||
|
| h :: t ->
|
||||||
|
let towel_len = String.length h in
|
||||||
|
if String.starts_with ~prefix:h pattern then
|
||||||
|
Aoc.memoize memo
|
||||||
|
(count_matches memo towels)
|
||||||
|
(String.sub pattern towel_len (pattern_len - towel_len))
|
||||||
|
+ count_matched t
|
||||||
|
else count_matched t
|
||||||
|
in
|
||||||
|
if pattern_len = 0 then 1 else count_matched towels
|
||||||
|
|
||||||
|
let part1 (towels, patterns) =
|
||||||
|
List.map (Aoc.memoize memo (count_matches memo towels)) patterns
|
||||||
|
|> List.filter (( < ) 0)
|
||||||
|
|> List.length
|
||||||
|
|
||||||
|
let part2 (towels, patterns) =
|
||||||
|
List.map (Aoc.memoize memo (count_matches memo towels)) patterns
|
||||||
|
|> List.fold_left ( + ) 0
|
||||||
|
|
||||||
|
let _ =
|
||||||
|
Aoc.main towels_of_file [ (string_of_int, part1); (string_of_int, part2) ]
|
6
bin/dune
6
bin/dune
@@ -17,7 +17,8 @@
|
|||||||
day2415
|
day2415
|
||||||
day2416
|
day2416
|
||||||
day2417
|
day2417
|
||||||
day2418)
|
day2418
|
||||||
|
day2419)
|
||||||
(names
|
(names
|
||||||
day2401
|
day2401
|
||||||
day2402
|
day2402
|
||||||
@@ -36,5 +37,6 @@
|
|||||||
day2415
|
day2415
|
||||||
day2416
|
day2416
|
||||||
day2417
|
day2417
|
||||||
day2418)
|
day2418
|
||||||
|
day2419)
|
||||||
(libraries str aoc))
|
(libraries str aoc))
|
||||||
|
@@ -90,3 +90,11 @@ let pow10 n =
|
|||||||
let rec impl acc = function 0 -> acc | x -> impl (acc * 10) (x - 1) in
|
let rec impl acc = function 0 -> acc | x -> impl (acc * 10) (x - 1) in
|
||||||
assert (n >= 0);
|
assert (n >= 0);
|
||||||
impl 1 n
|
impl 1 n
|
||||||
|
|
||||||
|
let memoize memo f value =
|
||||||
|
match Hashtbl.find_opt memo value with
|
||||||
|
| Some x -> x
|
||||||
|
| None ->
|
||||||
|
let x = f value in
|
||||||
|
Hashtbl.add memo value x;
|
||||||
|
x
|
||||||
|
@@ -30,6 +30,11 @@ val main : (string -> 'a) -> (('b -> string) * ('a -> 'b)) list -> unit
|
|||||||
[string_of_int]). The second executes the given part. Output is given as if
|
[string_of_int]). The second executes the given part. Output is given as if
|
||||||
done by: [print_string ( prep fname |> snd |> fst )] *)
|
done by: [print_string ( prep fname |> snd |> fst )] *)
|
||||||
|
|
||||||
|
val memoize : ('a, 'b) Hashtbl.t -> ('a -> 'b) -> 'a -> 'b
|
||||||
|
(** [memoize memo f value] returns the result of [f value]. The hashtable [memo]
|
||||||
|
is used to cache results, so repeated calls with the same [value] will not
|
||||||
|
call [f] again. *)
|
||||||
|
|
||||||
(** Module representing a pair of integers, useful for Set.Make *)
|
(** Module representing a pair of integers, useful for Set.Make *)
|
||||||
module IntPair : sig
|
module IntPair : sig
|
||||||
type t = int * int
|
type t = int * int
|
||||||
|
Reference in New Issue
Block a user