Files
aoc2024-elixir/lib/aoc2024/day_04.ex
T
Aurélien Geron 499a6f145d Solve day 4
2024-12-07 19:34:39 +13:00

103 lines
2.4 KiB
Elixir

defmodule Aoc2024.Day04 do
def parse(input) do
input |> String.split("\n", trim: true) |> Enum.map(&String.graphemes/1)
end
defp size(grid) do
height = length(grid)
width = grid |> Enum.map(&length/1) |> Enum.max()
{height, width}
end
def part1(grid) do
word_chars = "XMAS" |> String.graphemes()
{height, width} = grid |> size()
-1..1
|> Enum.map(fn dy ->
-1..1
|> Enum.map(fn dx ->
if dx == 0 && dy == 0 do
0
else
0..(height - 1)
|> Enum.map(fn y ->
0..(width - 1)
|> Enum.map(fn x ->
all_chars_ok =
word_chars
|> Enum.with_index()
|> Enum.all?(fn {char, index} ->
cy = y + index * dy
cx = x + index * dx
cond do
cy < 0 ->
false
cx < 0 ->
false
cy >= height ->
false
true ->
row = grid |> Enum.at(cy)
if cx >= length(row) do
false
else
row |> Enum.at(cx) == char
end
end
end)
if all_chars_ok do
1
else
0
end
end)
|> Enum.sum()
end)
|> Enum.sum()
end
end)
|> Enum.sum()
end)
|> Enum.sum()
end
def part2(grid) do
{height, width} = grid |> size()
0..(height - 3)
|> Enum.map(fn y ->
0..(width - 3)
|> Enum.map(fn x ->
center = grid |> Enum.at(y + 1) |> Enum.at(x + 1)
upper_left = grid |> Enum.at(y) |> Enum.at(x)
lower_right = grid |> Enum.at(y + 2) |> Enum.at(x + 2)
upper_right = grid |> Enum.at(y) |> Enum.at(x + 2)
lower_left = grid |> Enum.at(y + 2) |> Enum.at(x)
diag1? =
(upper_left == "M" && lower_right == "S") ||
(upper_left == "S" && lower_right == "M")
diag2? =
(upper_right == "M" && lower_left == "S") ||
(upper_right == "S" && lower_left == "M")
if center == "A" && diag1? && diag2? do
1
else
0
end
end)
|> Enum.sum()
end)
|> Enum.sum()
end
end