Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 6: Lanternfish

2021/elixir/day-06.livemd

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(&amp;IO.inspect(&amp;1, label: "Day #{day}"))
    end)
  end
end

Kino.Input.read(input)
|> String.split(",", trim: true)
|> Enum.map(&amp;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, &amp;Map.get(state, &amp;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(&amp;String.to_integer/1)
|> Enum.frequencies()
|> M.spawn(256)
|> Enum.sum()