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

Advent of Code 2024

2024/day04.livemd

Advent of Code 2024

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

Day 4

input =
  "https://adventofcode.com/2024/day/4/input"
  |> Req.get!(headers: [cookie: "session=#{System.get_env("AOC_COOKIE")}"])
  |> Map.get(:body)
sample = """
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
"""
defmodule Day4 do
  def parse(input) do
    rows =
      input
      |> String.split("\n", trim: true)
      |> Enum.map(&String.split(&1, "", trim: true))

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

  def find_coords(grid, letter) do
    grid
    |> Enum.filter(fn {_k, v} -> v == letter end)
    |> Enum.map(&amp;elem(&amp;1, 0))
  end
end
import Day4

Part 1

grid =
  input
  |> parse()

grid
|> find_coords("X")
|> Enum.flat_map(fn {x, y} ->
  [{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}]
  |> Enum.map(fn {dx, dy} ->
    {x + dx, y + dy}
    |> Stream.iterate(fn {x, y} -> {x + dx, y + dy} end)
    |> Enum.take(3)
    |> Enum.map_join(&amp;Map.get(grid, &amp;1))
  end)
end)
|> Enum.count(&amp;(&amp;1 == "MAS"))

Part 2

grid
|> find_coords("A")
|> Enum.filter(fn {x, y} ->
  [{-1, -1}, {1, 1}, {1, -1}, {-1, 1}]
  |> Enum.map(fn {dx, dy} -> Map.get(grid, {x + dx, y + dy}) end)
  |> Enum.chunk_every(2)
  |> Enum.all?(&amp;(&amp;1 in [["M", "S"], ["S", "M"]]))
end)
|> Enum.count()