Day11
Setup
Mix.install(
[
{:kino, "~> 0.4.1"}
],
consolidate_protocols: false
)
input = Kino.Input.textarea("Please paste your input:")
# 5483143223
# 2745854711
# 5264556173
# 6141336146
# 6357385478
# 4167524645
# 2176841721
# 6882881134
# 4846848554
# 5283751526
# 11111
# 19991
# 19191
# 19991
# 11111
# Input
2_682_551_651
3_223_134_263
5_848_471_412
7_438_334_862
8_731_321_573
6_415_233_574
5_564_726_843
6_683_456_445
8_582_346_112
4_617_588_236
lines =
input
|> Kino.Input.read()
|> String.split(["\n"], trim: true)
grid =
for {line, row} <- Enum.with_index(lines),
{number, col} <- Enum.with_index(String.to_charlist(line)),
into: %{} do
{{col, row}, number - ?0}
end
Map.update(grid, :lines, Enum.count(lines), & &1)
Part 1
defmodule Recursion do
def energize({grid, blinks}, {row, col} = point) do
cond do
grid[point] == nil ->
{grid, blinks}
grid[point] > 9 ->
{grid, blinks}
grid[point] == 9 ->
energize({Map.update(grid, point, nil, &(&1 + 1)), blinks + 1}, {row + 1, col})
|> energize({row + 1, col + 1})
|> energize({row, col + 1})
|> energize({row - 1, col})
|> energize({row - 1, col - 1})
|> energize({row, col - 1})
|> energize({row + 1, col - 1})
|> energize({row - 1, col + 1})
true ->
{Map.update(grid, point, nil, &(&1 + 1)), blinks}
end
end
def step(result, _count = 0) do
result
end
def step({grid, blinks}, count) do
{grid, blinks} =
Map.keys(grid)
|> Enum.reduce({grid, blinks}, fn point, {grid, blinks} ->
energize({grid, blinks}, point)
end)
grid =
grid
|> Map.new(fn {point, value} ->
cond do
value > 9 -> {point, 0}
true -> {point, value}
end
end)
step({grid, blinks}, count - 1)
end
end
{final_grid, blinks} = Recursion.step({grid, 0}, 100)
blinks
Part 2
Stream.iterate(1, &(&1 + 1))
|> Enum.reduce_while({grid, 0}, fn i, {grid, blink} ->
{grid, blink} = Recursion.step({grid, blink}, 1)
result =
for {_, value} <- grid,
value != 0,
do: true
cond do
result == [] -> {:halt, i}
true -> {:cont, {grid, blink}}
end
end)