# Advent of Code 2023 - Day 13

Hey, coding champions! Ukrainian Erlanger here , welcoming you to a wonderful Wednesday. It’s Day 13 of the captivating Advent of Code, and a brand-new puzzle is awaiting your coding expertise. Embrace the challenge, tackle the problem, and don’t forget to showcase your brilliant solutions in the comments below. Let’s keep the collaborative coding spirit alive and make this Wednesday a day of triumph! Happy coding, folks!

3 Likes

Today went better than yesterday for sure

``````defmodule Aoc.Thirteen do
def parse(string) do
string
|> String.split("\n\n", trim: true)
|> Enum.map(fn block ->
block
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
line
|> String.graphemes()
end)
end)
end

for {line, y} <- Enum.with_index(data, 1), {i, x} <- Enum.with_index(line, 1), into: %{} do
{{x, y}, i}
end
end

def part_one(input) do
input
|> Enum.map(&find_reflection/1)
|> Enum.map(&reflection_value/1)
|> Enum.sum()
end

def part_two(input) do
input
|> Enum.map(&smudge_and_reflect/1)
|> Enum.map(&reflection_value/1)
|> Enum.sum()
end

defp find_reflection(map) do
{max_x, max_y} = map |> Map.keys() |> Enum.max()

cols =
for x <- 1..(max_x - 1), is_reflection_col?(x, max_x, max_y, map) do
x
end

rows =
for y <- 1..(max_y - 1), is_reflection_row?(y, max_x, max_y, map) do
y
end

{cols, rows}
end

defp is_reflection_col?(x, max_x, max_y, map) do
{l_range, r_range} = trim(x..1, (x + 1)..max_x)
left = Enum.map(l_range, &scan_column(&1, max_y, map))
right = Enum.map(r_range, &scan_column(&1, max_y, map))
left == right
end

defp is_reflection_row?(y, max_x, max_y, map) do
{l_range, r_range} = trim(y..1, (y + 1)..max_y)
left = Enum.map(l_range, &scan_row(&1, max_x, map))
right = Enum.map(r_range, &scan_row(&1, max_x, map))
left == right
end

defp trim(l_range, r_range) do
ll = Enum.count(l_range)
lr = Enum.count(r_range)

if ll > lr do
{Enum.take(l_range, lr), r_range}
else
{l_range, Enum.take(r_range, ll)}
end
end

defp scan_row(y, max_x, map) do
for x <- 1..max_x do
Map.get(map, {x, y})
end
end

defp scan_column(x, max_y, map) do
for y <- 1..max_y do
Map.get(map, {x, y})
end
end

defp reflection_value({cols, rows}) do
Enum.sum(cols) + (rows |> Enum.map(& &1 * 100) |> Enum.sum())
end

defp smudge_and_reflect(map) do
og = map |> find_reflection()

map
|> smudge()
|> Enum.reduce_while(og, fn map, {cols0, rows0} = acc ->
{cols, rows} = find_reflection(map)
case {cols -- cols0, rows -- rows0} do
{[], []} -> {:cont, acc}
new      -> {:halt, new}
end
end)
end

defp smudge(map) do
{max_x, max_y} = map |> Map.keys() |> Enum.max()

for x <- 1..max_x, y <- 1..max_y do
Map.update(map, {x, y}, nil, fn "#" -> "."; "." -> "#" end)
end
end
end