Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code - 2024 Day 8

2024/day-08.livemd

Advent of Code - 2024 Day 8

Mix.install([
  {:kino_aoc, "~> 0.1.7"}
])

Part 1

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "8", System.fetch_env!("LB_AOC_SESSION"))
input =
  puzzle_input
  |> String.split("\n")
  |> Enum.map(&String.to_charlist/1)
grid =
  for {row, i} <- Enum.with_index(input),
      {char, j} <- Enum.with_index(row),
      char != ?.,
      into: %{},
      do: {{i, j}, char}
imax = length(input) - 1
jmax = length(hd(input)) - 1

Part 1

grid
|> Enum.group_by(&amp;elem(&amp;1, 1), &amp;elem(&amp;1, 0))
|> Map.values()
|> Enum.map(fn antennas ->
  for {i1, j1} = a1 <- antennas,
      {i2, j2} = a2 <- antennas,
      a1 != a2,
      di = i2 - i1,
      dj = j2 - j1 do
    [
      {i1 - di, j1 - dj},
      {i2 + di, j2 + dj}
    ]
  end
end)
|> List.flatten()
|> Enum.uniq()
|> Enum.count(fn {i, j} ->
  i in 0..imax and j in 0..jmax
end)

Part 2

grid
|> Enum.group_by(&amp;elem(&amp;1, 1), &amp;elem(&amp;1, 0))
|> Map.values()
|> Enum.map(fn antennas ->
  for {i1, j1} = a1 <- antennas,
      {i2, j2} = a2 <- antennas,
      a1 != a2,
      di = i2 - i1,
      dj = j2 - j1 do
    antinodes1 =
      a1
      |> Stream.iterate(fn {i, j} ->
        {i - di, j - dj}
      end)
      |> Enum.take_while(fn {i, j} ->
        i in 0..imax and j in 0..jmax
      end)

    antinodes2 =
      a1
      |> Stream.iterate(fn {i, j} ->
        {i + di, j + dj}
      end)
      |> Enum.take_while(fn {i, j} ->
        i in 0..imax and j in 0..jmax
      end)

    [antinodes1, antinodes2]
  end
end)
|> List.flatten()
|> Enum.uniq()
|> length()

Final State

final_grid =
  grid
  |> Enum.group_by(&amp;elem(&amp;1, 1), &amp;elem(&amp;1, 0))
  |> Map.values()
  |> Enum.map(fn antennas ->
    for {i1, j1} = a1 <- antennas,
        {i2, j2} = a2 <- antennas,
        a1 != a2,
        di = i2 - i1,
        dj = j2 - j1 do
      antinodes1 =
        a1
        |> Stream.iterate(fn {i, j} ->
          {i - di, j - dj}
        end)
        |> Enum.take_while(fn {i, j} ->
          i in 0..imax and j in 0..jmax
        end)
  
      antinodes2 =
        a1
        |> Stream.iterate(fn {i, j} ->
          {i + di, j + dj}
        end)
        |> Enum.take_while(fn {i, j} ->
          i in 0..imax and j in 0..jmax
        end)
  
      [antinodes1, antinodes2]
    end
  end)
  |> List.flatten()
  |> Enum.uniq()
  |> Map.new(&amp;{&amp;1, ?#})
  |> Map.merge(grid)
for i <- 0..imax do
  for j <- 0..jmax do
    final_grid[{i, j}] || ?.
  end
end
|> Enum.join("\n")
|> IO.puts()