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

Advent of Code 2024 Day 8 Part 1

2024_day8_part1.livemd

Advent of Code 2024 Day 8 Part 1

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

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "8", System.fetch_env!("LB_SESSION"))

My answer

sample_input =
  """
  ..........
  ..........
  ..........
  ....a.....
  ..........
  .....a....
  ..........
  ..........
  ..........
  ..........
  """
  |> String.trim()
parse = fn input ->
  input
  |> String.split("\n")
  |> Enum.with_index()
  |> Enum.flat_map(fn {row, row_index} ->
    row
    |> String.codepoints()
    |> Enum.with_index()
    |> Enum.map(fn {point, col_index} ->
      {{row_index, col_index}, point}
    end)
  end)
  |> Enum.into(%{})
end
map = parse.(sample_input)
find_pairs = fn map ->
  map
  |> Enum.reduce([], fn {{row_index, col_index}, point}, pairs ->
    case point do
      "." ->
        pairs

      mark ->
        map
        |> Enum.filter(fn {{pair_row_index, pair_col_index}, search_point} ->
          search_point == mark &amp;&amp; (row_index < pair_row_index or col_index < pair_col_index)
        end)
        |> Enum.map(fn {{pair_row_index, pair_col_index}, _} ->
          {{row_index, col_index}, {pair_row_index, pair_col_index}}
        end)
        |> Kernel.++(pairs)
    end
  end)
end
pairs = find_pairs.(map)
crate_antinodes = fn pairs, map ->
  max_row_index =
    map
    |> Enum.map(fn {{row_index, _}, _} -> row_index end)
    |> Enum.max()

  max_col_index =
    map
    |> Enum.map(fn {{_, col_index}, _} -> col_index end)
    |> Enum.max()

  IO.inspect({max_row_index, max_col_index}, label: "map size")

  pairs
  |> Enum.flat_map(fn {{row_index, col_index}, {pair_row_index, pair_col_index}} = pair ->
    f_row = pair_row_index - row_index
    f_col = pair_col_index - col_index

    IO.puts("")
    IO.inspect(pair, label: "pair")
    IO.inspect({f_row, f_col}, label: "frequency")

    [
      {row_index - f_row, col_index - f_col},
      {pair_row_index + f_row, pair_col_index + f_col}
    ]
    |> Enum.filter(fn {r, c} ->
      r >= 0 and r <= max_row_index and c >= 0 and c <= max_col_index
    end)
    |> IO.inspect(label: "antinodes")
  end)
  |> Enum.reduce({map, 0}, fn antinode, {acc_map, acc_num} ->
    case Map.get(acc_map, antinode) do
      "#" ->
        {acc_map, acc_num}

      _ ->
        {Map.put(acc_map, antinode, "#"), acc_num + 1}
    end
  end)
end
{updated_map, num} = crate_antinodes.(pairs, map)
plot_map = fn map ->
  max_row_index =
    map
    |> Enum.map(fn {{row_index, _}, _} -> row_index end)
    |> Enum.max()

  max_col_index =
    map
    |> Enum.map(fn {{_, col_index}, _} -> col_index end)
    |> Enum.max()

  0..max_row_index
  |> Enum.map(fn row_index ->
    0..max_col_index
    |> Enum.reduce("", fn col_index, row ->
      row <> Map.get(map, {row_index, col_index})
    end)
  end)
  |> Enum.join("\n")
end
plot_map.(updated_map)
|> Kino.Text.new(terminal: true)
search_antinodes = fn input ->
  map =  parse.(input)

  map
  |> find_pairs.()
  |> IO.inspect(lablel: "pairs")
  |> crate_antinodes.(map)
end
{updated_map, num} =
  """
  ..........
  ..........
  ..........
  ....a.....
  ........a.
  .....a....
  ..........
  ..........
  ..........
  ..........
  """
  |> String.trim()
  |> search_antinodes.()

IO.puts("")
IO.inspect(num, label: "number of antinodes")

updated_map
|> plot_map.()
|> Kino.Text.new(terminal: true)
{updated_map, num} =
  """
  ..........
  ..........
  ..........
  ....a.....
  ........a.
  .....a....
  ..........
  ......A...
  ..........
  ..........
  """
  |> String.trim()
  |> search_antinodes.()

IO.puts("")
IO.inspect(num, label: "number of antinodes")

updated_map
|> plot_map.()
|> Kino.Text.new(terminal: true)
{updated_map, num} =
  """
  ............
  ........0...
  .....0......
  .......0....
  ....0.......
  ......A.....
  ............
  ............
  ........A...
  .........A..
  ............
  ............
  """
  |> String.trim()
  |> search_antinodes.()

IO.puts("")
IO.inspect(num, label: "number of antinodes")

updated_map
|> plot_map.()
|> Kino.Text.new(terminal: true)
{updated_map, num} = search_antinodes.(puzzle_input)

num