Compare commits

...

2 Commits

Author SHA1 Message Date
ryan
1ee3a5a3c5 solve day 9 :) 2023-10-05 15:56:02 -07:00
ryan
5e1c30637e move vec2 into a new file & add a pretty printer
now it shows up properly in utop !!
2023-10-05 15:55:05 -07:00
8 changed files with 2109 additions and 25 deletions

1
.ocamlinit Normal file
View File

@ -0,0 +1 @@
#install_printer Aoc.Vec2.pp;;

View File

@ -8,5 +8,6 @@ let () =
Day5.print ();
Day6.print ();
Day7.print ();
Day8.print ()
Day8.print ();
Day9.print ()
;;

2000
inputs/day9.tt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +1,8 @@
open Containers
module Vec2 : sig
type t
val directions : t list
val of_tuple : int * int -> t
val to_tuple : t -> int * int
val ( + ) : t -> t -> t
val at : 'a array array -> t -> 'a option
end = struct
type t = int * int
let directions = [ 1, 0; 0, 1; -1, 0; 0, -1 ]
let of_tuple x = x
let to_tuple x = x
let ( + ) a b = Pair.map_same2 ( + ) a b
let at grid point =
let x, y = to_tuple point in
let open Option.Infix in
let* row = Array.get_safe grid y in
Array.get_safe row x
;;
end
(* module Vec2 : sig *)
(* end = struct *)
(* end *)
let parse_grid () =
let lines = Utils.lines_of_input 8 in

68
src/day9.ml Normal file
View File

@ -0,0 +1,68 @@
open Containers
let parse_input () =
Utils.lines_of_input 9
|> List.concat_map (fun line ->
match String.split ~by:" " line with
| [ dir; count ] ->
let count = int_of_string count in
let dir =
match dir with
| "U" -> Vec2.up
| "D" -> Vec2.down
| "L" -> Vec2.left
| "R" -> Vec2.right
| _ -> failwith "failed to parse instructions"
in
List.init count (fun _ -> dir)
| _ -> failwith "failed to parse instructions")
;;
let next_pos head tail =
let dx, dy = Vec2.(to_tuple @@ (tail - head)) in
if abs dx <= 1 && abs dy <= 1
then tail
else (
let x_dir = if dx > 0 then Vec2.right else Vec2.left in
let y_dir = if dy > 0 then Vec2.up else Vec2.down in
let dir =
if abs dx = abs dy
then Vec2.(x_dir + y_dir)
else if abs dx > abs dy
then x_dir
else y_dir
in
Vec2.(head + dir))
;;
let solve length =
let moves = parse_input () in
let start = Vec2.of_tuple (0, 0) in
let tail = List.init (length - 1) (fun _ -> start) in
let _, _, last_knot_hist =
List.fold_left
(fun (head, tail, last_knot_hist) dir ->
let new_head = Vec2.(head + dir) in
let last_knot, new_tail =
List.fold_map
(fun head knot ->
let new_knot = next_pos head knot in
new_knot, new_knot)
new_head
tail
in
new_head, new_tail, last_knot :: last_knot_hist)
(start, tail, [ start ])
moves
in
last_knot_hist |> List.uniq ~eq:Vec2.( = ) |> List.length
;;
let part1 () = solve 2
let part2 () = solve 10
let print () =
Printf.(
printf "Day 9.1: %d\n" @@ part1 ();
printf "Day 9.2: %d\n" @@ part2 ())
;;

View File

@ -1,7 +1,7 @@
(library
(name aoc)
(libraries re containers dune-site)
(preprocess (pps ppx_regexp)))
(preprocess (pps ppx_regexp ppx_deriving.show)))
(env
(dev

21
src/vec2.ml Normal file
View File

@ -0,0 +1,21 @@
open Containers
type t = int * int [@@deriving show]
let up = 0, 1
let down = 0, -1
let left = -1, 0
let right = 1, 0
let directions = [ up; down; left; right ]
let of_tuple x = x
let to_tuple x = x
let ( + ) a b = Pair.map_same2 ( + ) a b
let ( - ) a b = Pair.map_same2 ( - ) a b
let ( = ) a b = Pair.equal ( = ) ( = ) a b
let at grid point =
let x, y = to_tuple point in
let open Option.Infix in
let* row = Array.get_safe grid y in
Array.get_safe row x
;;

13
src/vec2.mli Normal file
View File

@ -0,0 +1,13 @@
type t [@@deriving show] [@@ocaml.toplevel_printer]
val up : t
val down : t
val left : t
val right : t
val directions : t list
val of_tuple : int * int -> t
val to_tuple : t -> int * int
val ( + ) : t -> t -> t
val ( - ) : t -> t -> t
val ( = ) : t -> t -> bool
val at : 'a array array -> t -> 'a option