Advent of Code 2024 - Day 4

#!/usr/bin/env elixir

# Aoc 2024. day 4.

defmodule Part1 do
  @spec xmas(map(), non_neg_integer(), non_neg_integer()) :: non_neg_integer()
  def xmas(m, r, c) do
    b2i(unquote(:"xmas↑")(m, r, c)) +
    b2i(unquote(:"xmas↗")(m, r, c)) +
    b2i(unquote(:"xmas→")(m, r, c)) +
    b2i(unquote(:"xmas↘")(m, r, c)) +
    b2i(unquote(:"xmas↓")(m, r, c)) +
    b2i(unquote(:"xmas↙")(m, r, c)) +
    b2i(unquote(:"xmas←")(m, r, c)) +
    b2i(unquote(:"xmas↖")(m, r, c))
  end

  defp unquote(:"xmas↑")(m, r, c),
    do: m[{r,c}] == "X" && m[{r-1,c}] == "M" && m[{r-2,c}] == "A" && m[{r-3,c}] == "S"
  defp unquote(:"xmas↗")(m, r, c),
    do: m[{r,c}] == "X" && m[{r-1,c+1}] == "M" && m[{r-2,c+2}] == "A" && m[{r-3,c+3}] == "S"
  defp unquote(:"xmas→")(m, r, c),
    do: m[{r,c}] == "X" && m[{r,c+1}] == "M" && m[{r,c+2}] == "A" && m[{r,c+3}] == "S"
  defp unquote(:"xmas↘")(m, r, c),
    do: m[{r,c}] == "X" && m[{r+1,c+1}] == "M" && m[{r+2,c+2}] == "A" && m[{r+3,c+3}] == "S"
  defp unquote(:"xmas↓")(m, r, c),
    do: m[{r,c}] == "X" && m[{r+1,c}] == "M" && m[{r+2,c}] == "A" && m[{r+3,c}] == "S"
  defp unquote(:"xmas↙")(m, r, c),
    do: m[{r,c}] == "X" && m[{r+1,c-1}] == "M" && m[{r+2,c-2}] == "A" && m[{r+3,c-3}] == "S"
  defp unquote(:"xmas←")(m, r, c),
    do: m[{r,c}] == "X" && m[{r,c-1}] == "M" && m[{r,c-2}] == "A" && m[{r,c-3}] == "S"
  defp unquote(:"xmas↖")(m, r, c),
    do: m[{r,c}] == "X" && m[{r-1,c-1}] == "M" && m[{r-2,c-2}] == "A" && m[{r-3,c-3}] == "S"

    def b2i(true), do: 1
  def b2i(false), do: 0
end

map = File.stream!("../day04.txt")
  |> Stream.with_index()
  |> Enum.reduce(%{}, fn {line, row}, map ->
    line
    |> String.trim_trailing()
    |> String.codepoints()
    |> Enum.with_index()
    |> Enum.reduce(map, fn {c, col}, map -> Map.put(map, {row, col}, c) end)
  end)

# part 1
Enum.reduce(map, 0, fn {{r,c},_char}, n -> n+Part1.xmas(map, r, c) end)
|> IO.inspect(label: "part 1")

defmodule Part2 do
  @spec xmas(map(), non_neg_integer(), non_neg_integer()) :: boolean()
  def xmas(m, r, c) do
    unquote(:"xmas↗↙")(m, r, c) && unquote(:"xmas↖↘")(m, r, c)
  end
  defp unquote(:"xmas↗↙")(m, r, c),
    do:  m[{r,c}] == "A" && ((m[{r+1,c-1}] == "M" && m[{r-1,c+1}] == "S") || (m[{r+1,c-1}] == "S" && m[{r-1,c+1}] == "M"))
  defp unquote(:"xmas↖↘")(m, r, c),
    do:  m[{r,c}] == "A" && ((m[{r+1,c+1}] == "M" && m[{r-1,c-1}] == "S") || (m[{r+1,c+1}] == "S" && m[{r-1,c-1}] == "M"))
end

# part 2
Enum.reduce(map, 0, fn {{r,c},_char}, n -> n+Part1.b2i(Part2.xmas(map, r, c)) end)
|> IO.inspect(label: "part 2")
2 Likes