Powered by AppSignal & Oban Pro

Day 15: Beacon Exclusion Zone

Day 15: Beacon Exclusion Zone.livemd

Day 15: Beacon Exclusion Zone

Section

input = """
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
Sensor at x=9, y=16: closest beacon is at x=10, y=16
Sensor at x=13, y=2: closest beacon is at x=15, y=3
Sensor at x=12, y=14: closest beacon is at x=10, y=16
Sensor at x=10, y=20: closest beacon is at x=10, y=16
Sensor at x=14, y=17: closest beacon is at x=10, y=16
Sensor at x=8, y=7: closest beacon is at x=2, y=10
Sensor at x=2, y=0: closest beacon is at x=2, y=10
Sensor at x=0, y=11: closest beacon is at x=2, y=10
Sensor at x=20, y=14: closest beacon is at x=25, y=17
Sensor at x=17, y=20: closest beacon is at x=21, y=22
Sensor at x=16, y=7: closest beacon is at x=15, y=3
Sensor at x=14, y=3: closest beacon is at x=15, y=3
Sensor at x=20, y=1: closest beacon is at x=15, y=3
"""

input = """
Sensor at x=3842919, y=126080: closest beacon is at x=3943893, y=1918172
Sensor at x=406527, y=2094318: closest beacon is at x=-1066, y=1333278
Sensor at x=2208821, y=3683408: closest beacon is at x=2914373, y=3062268
Sensor at x=39441, y=1251806: closest beacon is at x=-1066, y=1333278
Sensor at x=3093352, y=2404566: closest beacon is at x=2810772, y=2699609
Sensor at x=3645473, y=2234498: closest beacon is at x=3943893, y=1918172
Sensor at x=3645012, y=2995540: closest beacon is at x=4001806, y=2787325
Sensor at x=18039, y=3083937: closest beacon is at x=103421, y=3007511
Sensor at x=2375680, y=551123: closest beacon is at x=2761373, y=2000000
Sensor at x=776553, y=123250: closest beacon is at x=-1066, y=1333278
Sensor at x=2884996, y=2022644: closest beacon is at x=2761373, y=2000000
Sensor at x=1886537, y=2659379: closest beacon is at x=2810772, y=2699609
Sensor at x=3980015, y=3987237: closest beacon is at x=3844688, y=3570059
Sensor at x=3426483, y=3353349: closest beacon is at x=3844688, y=3570059
Sensor at x=999596, y=1165648: closest beacon is at x=-1066, y=1333278
Sensor at x=2518209, y=2287271: closest beacon is at x=2761373, y=2000000
Sensor at x=3982110, y=3262128: closest beacon is at x=3844688, y=3570059
Sensor at x=3412896, y=3999288: closest beacon is at x=3844688, y=3570059
Sensor at x=2716180, y=2798731: closest beacon is at x=2810772, y=2699609
Sensor at x=3575486, y=1273265: closest beacon is at x=3943893, y=1918172
Sensor at x=7606, y=2926795: closest beacon is at x=103421, y=3007511
Sensor at x=2719370, y=2062251: closest beacon is at x=2761373, y=2000000
Sensor at x=1603268, y=1771299: closest beacon is at x=2761373, y=2000000
Sensor at x=3999678, y=1864727: closest beacon is at x=3943893, y=1918172
Sensor at x=3157947, y=2833781: closest beacon is at x=2914373, y=3062268
Sensor at x=3904662, y=2601010: closest beacon is at x=4001806, y=2787325
Sensor at x=3846359, y=1608423: closest beacon is at x=3943893, y=1918172
Sensor at x=2831842, y=3562642: closest beacon is at x=2914373, y=3062268
Sensor at x=3157592, y=1874755: closest beacon is at x=2761373, y=2000000
Sensor at x=934300, y=2824967: closest beacon is at x=103421, y=3007511
Sensor at x=3986911, y=1907590: closest beacon is at x=3943893, y=1918172
Sensor at x=200888, y=3579976: closest beacon is at x=103421, y=3007511
Sensor at x=967209, y=3837958: closest beacon is at x=103421, y=3007511
Sensor at x=3998480, y=1972726: closest beacon is at x=3943893, y=1918172
"""
defmodule D15 do
  def parse_line(raw_line) do
    raw_line
    |> String.split(": ")
    |> Enum.map(&fetch_cord/1)
    |> Enum.map(&amp;(Code.eval_string("{" <> &amp;1 <> "}") |> elem(0)))
    |> List.to_tuple()
  end

  defp fetch_cord("closest beacon is at " <> cord), do: cord
  defp fetch_cord("Sensor at " <> cord), do: cord

  def add_manhattan_distance({{x1, y1} = sensor, {x2, y2} = beacon}) do
    {sensor, beacon, abs(x1 - x2) + abs(y1 - y2)}
  end

  def in_y_scope({{_, y}, _, dis}, target_y) do
    target_y in (y + dis)..(y - dis)
  end

  def expand_area({{x1, y1} = sensor, _beacon, dist}, target_y) do
    for x <- (x1 - dist)..(x1 + dist),
        y <- (y1 - dist)..(y1 + dist),
        abs(x - x1) + abs(y - y1) <= dist,
        y == target_y do
      {x, y}
    end
  end
end

y = 10

in_scope =
  input
  |> String.split("\n", trim: true)
  |> Stream.map(&amp;D15.parse_line/1)
  |> Stream.map(&amp;D15.add_manhattan_distance/1)

# |> Stream.filter(&D15.in_y_scope(&1, y))

sb =
  in_scope
  |> Enum.flat_map(fn {s, b, d} -> [s, b] end)

b =
  in_scope
  |> Enum.flat_map(fn {s, b, d} -> [b] end)

in_scope
|> Stream.flat_map(&amp;D15.expand_area(&amp;1, y))
|> Stream.filter(&amp;(elem(&amp;1, 1) == y))
|> Enum.uniq()
|> Kernel.--(b)
|> Enum.count()

# |> IO.inspect(limit: :infinity)