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