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

Advent of Code 2024

2024/day08.livemd

Advent of Code 2024

Mix.install([
  {:req, "~> 0.3.2"}
])

Day 8

input =
  "https://adventofcode.com/2024/day/8/input"
  |> Req.get!(headers: [cookie: "session=#{System.get_env("AOC_COOKIE")}"])
  |> Map.get(:body)
sample = """
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
"""
defmodule Day8 do
  def parse(input) do
    lines =
      input
      |> String.split("\n", trim: true)
      |> Enum.map(&String.split(&1, "", trim: true))

    for {row, y} <- Enum.with_index(lines),
        {val, x} <- Enum.with_index(row),
        into: %{},
        do: {{x, y}, val}
  end

  def expand(grid, [{x, y} | _] = acc, {dx, dy}) do
    next = {x + dx, y + dy}

    if Map.has_key?(grid, next) do
      expand(grid, [next | acc], {dx, dy})
    else
      acc
    end
  end
end
import Day8

Part 1

grid =
  input
  |> parse()

grid
|> Enum.reject(fn {_k, v} -> v == "." end)
|> Enum.group_by(fn {_k, v} -> v end)
|> Enum.map(fn {k, v} -> {k, Enum.map(v, &amp;elem(&amp;1, 0))} end)
|> Enum.flat_map(fn {_k, coords} ->
  (for x <- coords, y <- coords, x < y, do: {x, y})
  |> Enum.flat_map(fn {{x1, y1}, {x2, y2}} ->
    dx = x1 - x2
    dy = y1 - y2

    [{x1 + dx, y1 + dy}, {x2 - dx, y2 - dy}]
  end)
end)
|> Enum.into(MapSet.new())
|> Enum.filter(&amp; Map.has_key?(grid, &amp;1))
|> Enum.count()

Part 2

grid =
  input
  |> parse()

grid
|> Enum.reject(fn {_k, v} -> v == "." end)
|> Enum.group_by(fn {_k, v} -> v end)
|> Enum.map(fn {k, v} -> {k, Enum.map(v, &amp;elem(&amp;1, 0))} end)
|> Enum.flat_map(fn {_k, coords} ->
  for(x <- coords, y <- coords, x < y, do: {x, y})
  |> Enum.flat_map(fn {{x1, y1}, {x2, y2}} ->
    dx = x1 - x2
    dy = y1 - y2

    [
      expand(grid, [{x1, y1}], {dx, dy}),
      expand(grid, [{x2, y2}], {-dx, -dy})
    ]
    |> List.flatten()
  end)
end)
|> Enum.into(MapSet.new())
|> Enum.count()