Compare commits

...

3 Commits

Author SHA1 Message Date
ryan
b89e9c05ef refac day 14 to use new Vec2.bounds function 2023-11-08 10:37:44 -08:00
ryan
b90478cd03 solve day 15 part 1 ! 2023-11-08 10:37:31 -08:00
ryan
383c6c0fca add Vec2.iter_region 2023-11-08 10:36:33 -08:00
5 changed files with 65 additions and 37 deletions

View File

@ -44,18 +44,8 @@ let draw_rocks grid points =
let parse_grid lines start =
let points = List.map parse_line lines in
let lx, hx, ly, hy =
points
|> List.flatten
|> List.append [ start ]
|> List.fold_left
(fun (lx, hx, ly, hy) Vec2.{ x; y } ->
let lx = min lx x in
let hx = max hx x in
let ly = min ly y in
let hy = max hy y in
lx, hx, ly, hy)
(Int.max_int, 0, Int.max_int, 0)
let Vec2.{ x = lx; y = ly }, Vec2.{ x = hx; y = hy } =
points |> List.flatten |> List.append [ start ] |> Vec2.bounds 0
in
let pad_floor = 1 in
let pad_x = 2 in

View File

@ -44,22 +44,30 @@ let example_lines =
]
;;
let%expect_test "Day 15 example" =
example_lines |> List.map parse_sensor |> List.iter @@ Format.printf "%a@ " pp_sensor;
[%expect
{|
{ pos = (2, 18); beacon = (-2, 15); dist = 7 }
{ pos = (9, 16); beacon = (10, 16); dist = 1 }
{ pos = (13, 2); beacon = (15, 3); dist = 3 }
{ pos = (12, 14); beacon = (10, 16); dist = 4 }
{ pos = (10, 20); beacon = (10, 16); dist = 4 }
{ pos = (14, 17); beacon = (10, 16); dist = 5 }
{ pos = (8, 7); beacon = (2, 10); dist = 9 }
{ pos = (2, 0); beacon = (2, 10); dist = 10 }
{ pos = (0, 11); beacon = (2, 10); dist = 3 }
{ pos = (20, 14); beacon = (25, 17); dist = 8 }
{ pos = (17, 20); beacon = (21, 22); dist = 6 }
{ pos = (16, 7); beacon = (15, 3); dist = 5 }
{ pos = (14, 3); beacon = (15, 3); dist = 1 }
{ pos = (20, 1); beacon = (15, 3); dist = 7 } |}]
let bounds sensors =
let max_dist = sensors |> List.fold_left (fun acc s -> max acc s.dist) 0 in
sensors
|> List.flat_map (fun sensor -> [ sensor.pos; sensor.beacon ])
|> Vec2.bounds max_dist
;;
let%expect_test "Day 15.1" =
let sensors = Utils.lines_of_input 15 |> List.map parse_sensor in
let scan_row = 2000000 in
let Vec2.{ x = lx; _ }, Vec2.{ x = hx; _ } = bounds sensors in
let is_impossible pos =
sensors
|> List.map (fun s ->
let d = taxicab_dist pos s.pos in
if d <= s.dist && not Vec2.(pos = s.beacon) then 1 else 0)
|> List.reduce_exn ( + )
|> Int.sign
in
Vec2.fold_region
Vec2.{ x = lx; y = scan_row }
Vec2.{ x = hx; y = scan_row }
(fun acc pos -> acc + is_impossible pos)
0
|> Printf.printf "%i\n";
[%expect {| 5525990 |}]
;;

View File

@ -73,13 +73,7 @@ let of_lines parse_char lines : 'a t =
;;
let iter_region grid a b callback =
let open Vec2 in
for y = min a.y b.y to max a.y b.y do
for x = min a.x b.x to max a.x b.x do
let pos = { x; y } in
if in_bounds grid pos then callback pos
done
done
Vec2.iter_region a b (fun pos -> if in_bounds grid pos then callback pos)
;;
let iter grid callback =

View File

@ -19,3 +19,36 @@ let ( + ) a b = { x = a.x + b.x; y = a.y + b.y }
let ( - ) a b = { x = a.x - b.x; y = a.y - b.y }
let ( = ) a b = a.x = b.x && a.y = b.y
let abs a = Int.{ x = abs a.x; y = abs a.y }
let iter_region a b callback =
for y = min a.y b.y to max a.y b.y do
for x = min a.x b.x to max a.x b.x do
callback { x; y }
done
done
;;
let fold_region a b callback init =
let acc = ref init in
iter_region a b (fun pos -> acc := callback !acc pos);
!acc
;;
let bounds padding points =
let lx, hx, ly, hy =
points
|> List.fold_left
(fun (lx, hx, ly, hy) { x; y } ->
let lx = min lx x in
let hx = max hx x in
let ly = min ly y in
let hy = max hy y in
lx, hx, ly, hy)
(Int.max_int, 0, Int.max_int, 0)
in
let lx = Int.(lx - padding) in
let hx = Int.(hx + padding) in
let ly = Int.(ly - padding) in
let hy = Int.(hy + padding) in
of_tuple (lx, ly), of_tuple (hx, hy)
;;

View File

@ -17,3 +17,6 @@ val ( + ) : t -> t -> t
val ( - ) : t -> t -> t
val ( = ) : t -> t -> bool
val abs : t -> t
val iter_region : t -> t -> (t -> unit) -> unit
val fold_region : t -> t -> ('a -> t -> 'a) -> 'a -> 'a
val bounds : int -> t list -> t * t