Day 6: Lanternfish
Setup
Mix.install([
{:kino, "~> 0.4.1"}
])
Input
input = Kino.Input.textarea("Input")
Part 1
defmodule M do
@spawn_timer 8
@loop_timer 6
def spawn(initial_state, days) do
Enum.reduce(1..days, initial_state, fn day, state ->
{state, n_spawn} =
Enum.map_reduce(state, 0, fn timer, n_spawn ->
if timer - 1 < 0, do: {@loop_timer, n_spawn + 1}, else: {timer - 1, n_spawn}
end)
(state ++ List.duplicate(@spawn_timer, n_spawn))
|> tap(&IO.inspect(&1, label: "Day #{day}"))
end)
end
end
Kino.Input.read(input)
|> String.split(",", trim: true)
|> Enum.map(&String.to_integer/1)
|> M.spawn(80)
|> Enum.count()
Part 2
defmodule M do
def spawn(state, days) when is_map(state) do
Enum.map(0..8, &Map.get(state, &1, 0))
|> M.spawn(days)
end
def spawn(state = [t0, t1, t2, t3, t4, t5, t6, t7, t8], days) when is_list(state) do
if days == 0 do
state
else
M.spawn([t1, t2, t3, t4, t5, t6, t7 + t0, t8, t0], days - 1)
end
end
end
Kino.Input.read(input)
|> String.split(",", trim: true)
|> Enum.map(&String.to_integer/1)
|> Enum.frequencies()
|> M.spawn(256)
|> Enum.sum()