Compare commits
2 Commits
030fd73bab
...
main
Author | SHA1 | Date | |
---|---|---|---|
aea9724914
|
|||
43b47b2a34
|
@@ -129,7 +129,8 @@ let rec execute_until_halted vm =
|
|||||||
| false -> execute_until_halted (execute_insn vm)
|
| false -> execute_until_halted (execute_insn vm)
|
||||||
|
|
||||||
(** [string_of_ouput vm] gives the output of [vm]. *)
|
(** [string_of_ouput vm] gives the output of [vm]. *)
|
||||||
let string_of_output vm =
|
let part1 vm =
|
||||||
|
let vm = execute_until_halted vm in
|
||||||
List.rev vm.out |> List.map string_of_int |> String.concat ","
|
List.rev vm.out |> List.map string_of_int |> String.concat ","
|
||||||
|
|
||||||
(** [scan_digit acc ip vm] updates the acc for A so that the output of running
|
(** [scan_digit acc ip vm] updates the acc for A so that the output of running
|
||||||
@@ -159,8 +160,8 @@ let scan_all vm =
|
|||||||
impl 0 (Array.length vm.code - 1)
|
impl 0 (Array.length vm.code - 1)
|
||||||
|
|
||||||
(** [string_of_a vm] returns the A register of [vm]. *)
|
(** [string_of_a vm] returns the A register of [vm]. *)
|
||||||
let string_of_a vm = string_of_int vm.a
|
let part2 vm =
|
||||||
|
let vm = scan_all vm in
|
||||||
|
string_of_int vm.a
|
||||||
|
|
||||||
let _ =
|
let _ = Aoc.main vm_of_file [ (Fun.id, part1); (Fun.id, part2) ]
|
||||||
Aoc.main vm_of_file
|
|
||||||
[ (string_of_output, execute_until_halted); (string_of_a, scan_all) ]
|
|
||||||
|
@@ -104,12 +104,12 @@ let find_route_length count grid =
|
|||||||
let part1 count rocks =
|
let part1 count rocks =
|
||||||
match find_route_length count rocks with
|
match find_route_length count rocks with
|
||||||
| None -> failwith "part1"
|
| None -> failwith "part1"
|
||||||
| Some (cost, _) -> cost
|
| Some (cost, _) -> string_of_int cost
|
||||||
|
|
||||||
(** [part2 start_count grid] returns the location of the first rock to fall into
|
(** [part2 start_count grid] returns the location of the first rock to fall into
|
||||||
[grid] which makes it impossible to get from the top-left to bottom-right.
|
[grid] which makes it impossible to get from the top-left to bottom-right.
|
||||||
*)
|
*)
|
||||||
let part2 start_count grid =
|
let part2 width start_count grid =
|
||||||
(* Implementation notes:
|
(* Implementation notes:
|
||||||
|
|
||||||
We do this by binary search in impl. The left_count is a known count of
|
We do this by binary search in impl. The left_count is a known count of
|
||||||
@@ -137,16 +137,11 @@ let part2 start_count grid =
|
|||||||
let count = impl start_count (1 + count_rocks 0 0) in
|
let count = impl start_count (1 + count_rocks 0 0) in
|
||||||
match Array.find_index (( = ) (count - 1)) grid.grid with
|
match Array.find_index (( = ) (count - 1)) grid.grid with
|
||||||
| None -> failwith "part2"
|
| None -> failwith "part2"
|
||||||
| Some idx -> idx
|
| Some idx -> Printf.sprintf "%d,%d" (idx mod width) (idx / width)
|
||||||
|
|
||||||
(** [string_of_idx width idx] prints the (x, y) location for a given index in a
|
|
||||||
grid. *)
|
|
||||||
let string_of_idx width idx =
|
|
||||||
Printf.sprintf "%d,%d" (idx mod width) (idx / width)
|
|
||||||
|
|
||||||
(** Width of grid *)
|
(** Width of grid *)
|
||||||
let width = 71
|
let width = 71
|
||||||
|
|
||||||
let _ =
|
let _ =
|
||||||
Aoc.main (grid_of_file width)
|
Aoc.main (grid_of_file width)
|
||||||
[ (string_of_int, part1 1024); (string_of_idx width, part2 1024) ]
|
[ (Fun.id, part1 1024); (Fun.id, part2 width 1024) ]
|
||||||
|
34
bin/day2425.ml
Normal file
34
bin/day2425.ml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
let pin_count = 5
|
||||||
|
let height = 7
|
||||||
|
|
||||||
|
let read_lock_or_key lst =
|
||||||
|
let result = Array.make pin_count 0 in
|
||||||
|
let add_node i c = if c = '#' then result.(i) <- result.(i) + 1 in
|
||||||
|
List.iter (String.iteri add_node) lst;
|
||||||
|
result |> Array.to_list
|
||||||
|
|
||||||
|
let locks_and_keys_of_list =
|
||||||
|
let rec impl locks keys = function
|
||||||
|
| [] -> (locks, keys)
|
||||||
|
| "" :: t -> impl locks keys t
|
||||||
|
| a :: b :: c :: d :: e :: f :: g :: t ->
|
||||||
|
let h = read_lock_or_key [ a; b; c; d; e; f; g ] in
|
||||||
|
if a = String.make pin_count '#' then impl locks (h :: keys) t
|
||||||
|
else impl (h :: locks) keys t
|
||||||
|
| _ -> failwith "locks_and_keys_of_list"
|
||||||
|
in
|
||||||
|
impl [] []
|
||||||
|
|
||||||
|
let locks_and_keys_of_file fname =
|
||||||
|
Aoc.strings_of_file fname |> locks_and_keys_of_list
|
||||||
|
|
||||||
|
let lock_key_fit lock key =
|
||||||
|
List.map2 ( + ) lock key |> List.for_all (( >= ) height)
|
||||||
|
|
||||||
|
let count_keys keys lock = List.filter (lock_key_fit lock) keys |> List.length
|
||||||
|
|
||||||
|
let count_locks_and_keys (locks, keys) =
|
||||||
|
List.map (count_keys keys) locks |> List.fold_left ( + ) 0
|
||||||
|
|
||||||
|
let _ =
|
||||||
|
Aoc.main locks_and_keys_of_file [ (string_of_int, count_locks_and_keys) ]
|
Reference in New Issue
Block a user