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
|
||||
module VecTbl = Hashtbl.Make (Vec2)
|
||||
|
||||
type sensor =
|
||||
{ pos : Vec2.t
|
||||
|
|
@ -51,23 +52,72 @@ let bounds sensors =
|
|||
|> 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 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)
|
||||
(fun acc pos -> if could_be_beacon sensors false pos then acc else acc + 1)
|
||||
0
|
||||
|> Printf.printf "%i\n";
|
||||
[%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
|
||||
(name aoc)
|
||||
(libraries re containers dune-site angstrom)
|
||||
(libraries re containers iter dune-site angstrom)
|
||||
(inline_tests)
|
||||
(preprocess (pps
|
||||
ppx_regexp
|
||||
ppx_deriving.show
|
||||
ppx_deriving.eq
|
||||
ppx_deriving.ord
|
||||
ppx_deriving_hash
|
||||
ppx_expect
|
||||
ppx_inline_test)))
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ type t =
|
|||
{ x : int
|
||||
; y : int
|
||||
}
|
||||
[@@deriving eq, ord, hash]
|
||||
|
||||
let pp (fmt : Format.formatter) v = Format.fprintf fmt "(%i, %i)" v.x v.y
|
||||
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 ( + ) 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 iter_region a b callback =
|
||||
|
|
@ -52,3 +53,5 @@ let bounds padding points =
|
|||
let hy = Int.(hy + padding) in
|
||||
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
|
||||
; y : int
|
||||
}
|
||||
[@@deriving eq, ord, hash]
|
||||
|
||||
val show : t -> string
|
||||
val pp : Format.formatter -> t -> unit
|
||||
|
|
@ -20,3 +21,4 @@ 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
|
||||
val in_bounds : t -> t -> t -> bool
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user