Advent of Code 2023 - Day 13
Mix.install([
{:kino, "~> 0.11.0"},
{:kino_aoc, github: "ljgago/kino_aoc"}
])
Input
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2023", "13", System.fetch_env!("LB_AOC_SESSION"))
input =
puzzle_input
|> String.split("\n\n", trim: true)
|> Enum.map(fn row ->
row
|> String.split("\n", trim: true)
|> Enum.map(&String.graphemes/1)
end)
Part 1
find_reflection = fn pattern, compare_fun ->
count = Enum.count(pattern)
Enum.find_index(0..(count - 2), fn i ->
upper = Enum.slice(pattern, 0..i)
lower = Enum.slice(pattern, (i + 1)..count)
min = min(length(upper), length(lower))
upper_cut = Enum.slice(upper, -min..-1)
lower_cut = Enum.slice(lower, 0..(min - 1))
compare_fun.(lower_cut, Enum.reverse(upper_cut))
end)
end
summarize = fn pattern, compare_fun ->
for pattern <- pattern, reduce: 0 do
sum ->
flipped = Enum.zip_with(pattern, &Function.identity/1)
ih = find_reflection.(pattern, compare_fun)
iv = find_reflection.(flipped, compare_fun)
case {ih, iv} do
{i, nil} -> sum + (i + 1) * 100
{nil, i} -> sum + i + 1
end
end
end
input
|> summarize.(&(&1 == &2))
Part 2
defmodule Part2 do
def diff([], [], d), do: d
def diff([a1 | ar], [b1 | br], d) when a1 != b1, do: diff(ar, br, d + 1)
def diff([_ | ar], [_ | br], d), do: diff(ar, br, d)
end
input
|> summarize.(fn a, b ->
a = List.flatten(a)
b = List.flatten(b)
Part2.diff(a, b, 0) == 1
end)