#!/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