solve day 15 part 1 !

This commit is contained in:
ryan 2023-11-08 10:37:31 -08:00
parent 383c6c0fca
commit b90478cd03
3 changed files with 53 additions and 18 deletions

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

@ -27,3 +27,28 @@ let iter_region a b callback =
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

@ -18,3 +18,5 @@ 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