very slow solution to day 15 part 2 :)
could be sped up by doing math to find intesections points of the borders but that sounds boring
This commit is contained in:
parent
b89e9c05ef
commit
8d97e7601c
68
src/day15.ml
68
src/day15.ml
|
|
@ -1,4 +1,5 @@
|
||||||
open Containers
|
open Containers
|
||||||
|
module VecTbl = Hashtbl.Make (Vec2)
|
||||||
|
|
||||||
type sensor =
|
type sensor =
|
||||||
{ pos : Vec2.t
|
{ pos : Vec2.t
|
||||||
|
|
@ -51,23 +52,72 @@ let bounds sensors =
|
||||||
|> Vec2.bounds max_dist
|
|> Vec2.bounds max_dist
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
let could_be_beacon sensors ignore_known pos =
|
||||||
|
sensors
|
||||||
|
|> List.fold_while
|
||||||
|
(fun _ s ->
|
||||||
|
let d = taxicab_dist pos s.pos in
|
||||||
|
if d <= s.dist && (ignore_known || not Vec2.(pos = s.beacon))
|
||||||
|
then false, `Stop
|
||||||
|
else true, `Continue)
|
||||||
|
true
|
||||||
|
;;
|
||||||
|
|
||||||
let%expect_test "Day 15.1" =
|
let%expect_test "Day 15.1" =
|
||||||
let sensors = Utils.lines_of_input 15 |> List.map parse_sensor in
|
let sensors = Utils.lines_of_input 15 |> List.map parse_sensor in
|
||||||
let scan_row = 2000000 in
|
let scan_row = 2000000 in
|
||||||
let Vec2.{ x = lx; _ }, Vec2.{ x = hx; _ } = bounds sensors 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.fold_region
|
||||||
Vec2.{ x = lx; y = scan_row }
|
Vec2.{ x = lx; y = scan_row }
|
||||||
Vec2.{ x = hx; y = scan_row }
|
Vec2.{ x = hx; y = scan_row }
|
||||||
(fun acc pos -> acc + is_impossible pos)
|
(fun acc pos -> if could_be_beacon sensors false pos then acc else acc + 1)
|
||||||
0
|
0
|
||||||
|> Printf.printf "%i\n";
|
|> Printf.printf "%i\n";
|
||||||
[%expect {| 5525990 |}]
|
[%expect {| 5525990 |}]
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
let points_on_border tbl sensor =
|
||||||
|
let points = ref [] in
|
||||||
|
let dist = sensor.dist + 1 in
|
||||||
|
for d1 = 0 to dist do
|
||||||
|
let d2 = dist - d1 in
|
||||||
|
let open Vec2 in
|
||||||
|
let p1 = of_tuple (d1, d2) in
|
||||||
|
let p2 = of_tuple (d1, Int.(-d2)) in
|
||||||
|
let new_points =
|
||||||
|
[ sensor.pos + p1; sensor.pos - p1; sensor.pos + p2; sensor.pos - p2 ]
|
||||||
|
|> List.fold_left
|
||||||
|
(fun acc point ->
|
||||||
|
match VecTbl.mem tbl point with
|
||||||
|
| true -> point :: acc
|
||||||
|
| false ->
|
||||||
|
VecTbl.add tbl point ();
|
||||||
|
acc)
|
||||||
|
[]
|
||||||
|
in
|
||||||
|
points := !points @ new_points
|
||||||
|
done;
|
||||||
|
!points
|
||||||
|
;;
|
||||||
|
|
||||||
|
let%expect_test "Day 15.2" =
|
||||||
|
let sensors = Utils.lines_of_input 15 |> List.map parse_sensor in
|
||||||
|
let mult = 4000000 in
|
||||||
|
let range = mult in
|
||||||
|
let in_bounds = Vec2.(in_bounds origin @@ of_tuple (range, range)) in
|
||||||
|
let tbl = VecTbl.create (range * 10) in
|
||||||
|
let point =
|
||||||
|
sensors
|
||||||
|
|> Iter.of_list
|
||||||
|
|> Iter.flat_map_l @@ points_on_border tbl
|
||||||
|
|> Iter.fold_while
|
||||||
|
(fun _ v ->
|
||||||
|
if in_bounds v && could_be_beacon sensors true v
|
||||||
|
then Some v, `Stop
|
||||||
|
else None, `Continue)
|
||||||
|
None
|
||||||
|
|> Option.get_exn_or "fucc :("
|
||||||
|
in
|
||||||
|
Printf.printf "%i" ((mult * point.x) + point.y);
|
||||||
|
[%expect {| 11756174628223|}]
|
||||||
|
;;
|
||||||
|
|
|
||||||
5
src/dune
5
src/dune
|
|
@ -1,10 +1,13 @@
|
||||||
(library
|
(library
|
||||||
(name aoc)
|
(name aoc)
|
||||||
(libraries re containers dune-site angstrom)
|
(libraries re containers iter dune-site angstrom)
|
||||||
(inline_tests)
|
(inline_tests)
|
||||||
(preprocess (pps
|
(preprocess (pps
|
||||||
ppx_regexp
|
ppx_regexp
|
||||||
ppx_deriving.show
|
ppx_deriving.show
|
||||||
|
ppx_deriving.eq
|
||||||
|
ppx_deriving.ord
|
||||||
|
ppx_deriving_hash
|
||||||
ppx_expect
|
ppx_expect
|
||||||
ppx_inline_test)))
|
ppx_inline_test)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ type t =
|
||||||
{ x : int
|
{ x : int
|
||||||
; y : int
|
; y : int
|
||||||
}
|
}
|
||||||
|
[@@deriving eq, ord, hash]
|
||||||
|
|
||||||
let pp (fmt : Format.formatter) v = Format.fprintf fmt "(%i, %i)" v.x v.y
|
let pp (fmt : Format.formatter) v = Format.fprintf fmt "(%i, %i)" v.x v.y
|
||||||
let show v = Format.asprintf "%a" pp v
|
let show v = Format.asprintf "%a" pp v
|
||||||
|
|
@ -17,7 +18,7 @@ let of_tuple (x, y) = { x; y }
|
||||||
let to_tuple { x; y } = x, y
|
let to_tuple { x; y } = x, y
|
||||||
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 = { 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 ( = ) = equal
|
||||||
let abs a = Int.{ x = abs a.x; y = abs a.y }
|
let abs a = Int.{ x = abs a.x; y = abs a.y }
|
||||||
|
|
||||||
let iter_region a b callback =
|
let iter_region a b callback =
|
||||||
|
|
@ -52,3 +53,5 @@ let bounds padding points =
|
||||||
let hy = Int.(hy + padding) in
|
let hy = Int.(hy + padding) in
|
||||||
of_tuple (lx, ly), of_tuple (hx, hy)
|
of_tuple (lx, ly), of_tuple (hx, hy)
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
let in_bounds l h p = p.x >= l.x && p.x <= h.x && p.y >= l.y && p.y <= h.y
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ type t =
|
||||||
{ x : int
|
{ x : int
|
||||||
; y : int
|
; y : int
|
||||||
}
|
}
|
||||||
|
[@@deriving eq, ord, hash]
|
||||||
|
|
||||||
val show : t -> string
|
val show : t -> string
|
||||||
val pp : Format.formatter -> t -> unit
|
val pp : Format.formatter -> t -> unit
|
||||||
|
|
@ -20,3 +21,4 @@ val abs : t -> t
|
||||||
val iter_region : t -> t -> (t -> unit) -> unit
|
val iter_region : t -> t -> (t -> unit) -> unit
|
||||||
val fold_region : t -> t -> ('a -> t -> 'a) -> 'a -> 'a
|
val fold_region : t -> t -> ('a -> t -> 'a) -> 'a -> 'a
|
||||||
val bounds : int -> t list -> t * t
|
val bounds : int -> t list -> t * t
|
||||||
|
val in_bounds : t -> t -> t -> bool
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user