cosmetic refactoring for day 15

This commit is contained in:
ryan 2023-11-20 18:57:00 -08:00
parent 2887274ad9
commit d1e69ba66e

View File

@ -41,50 +41,47 @@ let could_be_beacon sensors ignore_known pos =
slope -1 passing thru bx + dist + 1, by
slope -1 passing thru bx - dist - 1, by
to find constant given slope, plug point into
to find the constant given a slope, plug a point into
c = y - m*x
constants are store separately for pos and neg slope boundaries
so that they can be handled separately
constants are stored separately for boundaries with positive and negative
slope so that they can be handled separately
p1 = y - bx - dist - 1
p2 = y - bx + dist + 1
n1 = y + bx + dist + 1
n2 = y + bx - dist - 1
]}*)
let get_coeffs sensors =
let get_consts sensors =
sensors
|> Iter.fold
(fun (pos_coeffs, neg_coeffs) { pos; beacon = _; dist } ->
(fun (p_slope_consts, n_slope_consts) { pos; beacon = _; dist } ->
let p1 = pos.y - pos.x + dist + 1 in
let p2 = pos.y - pos.x - dist - 1 in
let n1 = pos.y + pos.x + dist + 1 in
let n2 = pos.y + pos.x - dist - 1 in
Iter.(
append pos_coeffs (of_list [ p1; p2 ]), append neg_coeffs (of_list [ n1; n2 ])))
( append p_slope_consts (of_list [ p1; p2 ])
, append n_slope_consts (of_list [ n1; n2 ]) )))
(Iter.empty, Iter.empty)
;;
let%expect_test "Day 15.1" =
let sensors = Utils.lines_of_input 15 |> Iter.of_list |> Iter.map parse_sensor in
let scan_y = 2000000 in
let pos_coeffs, neg_coeffs = get_coeffs sensors in
let p_slope_consts, n_slope_consts = get_consts sensors in
(*{[
for a line y = c to intersect with a positive slope boundary:
y = c
y = x + n
c = x + p
x = c - p
for a known y to intersect with a positive slope boundary:
y = x + p
x = y - p
and for a negative slop boundary
y = c
and for a negative slope boundary:
y = -x + n
c = -x + n
x = n - c
x = n - y
]}*)
let intersection_xs =
Iter.append
(Iter.map (fun p -> scan_y - p) pos_coeffs)
(Iter.map (fun n -> n - scan_y) neg_coeffs)
(Iter.map (fun p -> scan_y - p) p_slope_consts)
(Iter.map (fun n -> n - scan_y) n_slope_consts)
|> Iter.sort_uniq ~cmp:Int.compare
in
(* iterate thru the intersections by ascending x.
@ -111,27 +108,21 @@ let%expect_test "Day 15.2" =
let mult = 4000000 in
let range = mult in
let in_bounds = Vec2.(in_bounds origin @@ of_tuple (range, range)) in
let pos_coeffs, neg_coeffs = get_coeffs sensors in
let p_slope_consts, n_slope_consts = get_consts sensors in
(*{[
boundaries only itersect if they have opposite slope.
to find the intersection, set equations to be equal and solve.
y = 1*x + p
y = -1*x + n // set equal
x + p = -x + n // add x
2x + p = n // subtract p
y = x + p
y = -x + n // set equal
x + p = -x + n // add x and subtract p
2x = n - p // divide 2
x = (n - p)/2 // substitute x into original
-> x = (n - p)/2 // substitute x into original
y = (n - p)/2 + p // multiply 2
2y = n + p // div 2
y = (n + p)/2
intersection point is at
x = (n - p)/2
y = (n + p)/2
-> y = (n + p)/2
]}*)
let point =
Iter.product pos_coeffs neg_coeffs
Iter.product p_slope_consts n_slope_consts
|> Iter.fold_while
(fun _ (p, n) ->
let i = Vec2.of_tuple ((n - p) / 2, (n + p) / 2) in