1
0
Fork 0
advent-of-code/2021/lib/2021/20.ex

105 lines
2.3 KiB
Elixir
Raw Normal View History

2022-09-21 09:19:54 -04:00
import AOC
aoc 2021, 20 do
import Integer, only: [is_even: 1]
def p1 do
{algorithm, source_image} = input()
enhance(source_image, algorithm, 2)
|> Map.values()
|> Enum.count(&(&1))
end
def p2 do
{algorithm, source_image} = input()
enhance(source_image, algorithm, 50)
|> Map.values()
|> Enum.count(&(&1))
end
def enhance(image, algorithm, to_iteration, iteration \\ 0)
def enhance(image, _algorithm, iteration, iteration), do: image
def enhance(image, algorithm, to_iteration, iteration) do
infinite_expanse = if is_even(iteration), do: Map.get(algorithm, 511), else: Map.get(algorithm, 0)
{i_range, j_range} = bounds(image)
for i <- i_range, j <- j_range, into: %{} do
{{i, j}, Map.get(algorithm, algorithm_idx(image, {i, j}, infinite_expanse))}
end
|> enhance(algorithm, to_iteration, iteration + 1)
end
def bounds(image) do
{{i_min, j_min}, {i_max, j_max}} =
image
|> Map.keys()
|> Enum.min_max()
{Range.new(i_min - 2, i_max + 2), Range.new(j_min - 2, j_max + 2)}
end
def algorithm_idx(image, {i, j}, infinite_expanse) do
[
{i - 1, j - 1},
{i - 1, j},
{i - 1, j + 1},
{i, j - 1},
{i, j},
{i, j + 1},
{i + 1, j - 1},
{i + 1, j},
{i + 1, j + 1}
]
|> Enum.map(&Map.get(image, &1, infinite_expanse))
|> Enum.map(fn
true -> 1
false -> 0
end)
|> Integer.undigits(2)
end
def input() do
[unparsed_algorithm, unparsed_source_image] =
input_string()
|> String.split("\n\n", trim: true)
algorithm =
unparsed_algorithm
|> String.split("", trim: true)
|> Enum.with_index()
|> Enum.map(fn
{"#", i} -> {i, true}
{".", i} -> {i, false}
end)
|> Enum.into(%{})
source_image =
unparsed_source_image
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
line
|> String.split("", trim: true)
|> Enum.map(fn
"#" -> true
"." -> false
end)
|> Enum.with_index()
end)
|> Enum.with_index()
|> then(&for(
{row, i} <- &1,
{cell, j} <- row,
into: %{},
do: {{i, j}, cell}
))
{algorithm, source_image}
end
end