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

Advent of Code 2021 day 06

2021/priv/day-06.livemd

Advent of Code 2021 day 06

Setup

Mix.install([
  {:kino, github: "livebook-dev/kino"},
  {:vega_lite, "~> 0.1.1"}
])
input = Kino.Input.textarea("Please type your input:")
fishes =
  input
  |> Kino.Input.read()
  |> String.split([",", "\n"], trim: true)
  |> Enum.map(&String.to_integer/1)

Part 1

defmodule Day6 do
  def grow(0) do
    [6, 8]
  end

  def grow(i), do: [i - 1]
end

days = 80

Enum.reduce(1..days, fishes, fn _, acc ->
  Enum.flat_map(acc, &Day6.grow/1)
end)
|> Enum.count()

Part2

defmodule Day6Part2 do
  def grow({prev0, prev1, prev2, prev3, prev4, prev5, prev6, prev7, prev8}) do
    {prev1, prev2, prev3, prev4, prev5, prev6, prev7 + prev0, prev8, prev0}
  end
end

frequencies = Enum.frequencies(fishes)

amounts = Enum.map(0..8, fn i -> frequencies[i] || 0 end) |> List.to_tuple()

1..256
|> Enum.reduce(amounts, fn _, amounts -> Day6Part2.grow(amounts) end)
|> Tuple.sum()

Visualization

alias VegaLite, as: Vl

graph =
  Vl.new(height: 400, width: 400)
  |> Vl.mark(:line)
  |> Vl.encode_field(:x, "day", type: :quantitative, scale: [domain: [0, 256]])
  |> Vl.encode_field(:y, "count", type: :quantitative)
  # |> Vl.encode_field(:y, "count", type: :quantitative, scale: [domain: [0, 1_700_000_000_000]])
  # |> Vl.encode_field(:y, "count", type: :quantitative, scale: [type: :log])
  |> Kino.VegaLite.new()
  |> Kino.render()

Kino.VegaLite.periodically(
  graph,
  # interval
  100,
  # accumulator
  {0, amounts},
  fn {day, {t0, t1, t2, t3, t4, t5, t6, t7, t8} = t} ->
    count = Tuple.sum(t)
    Kino.VegaLite.push(graph, %{day: day, count: count})

    if day < 256 do
      t = {t1, t2, t3, t4, t5, t6, t7 + t0, t8, t0}
      {:cont, {day + 1, t}}
    else
      IO.inspect(count, label: :count)
      :halt
    end
  end
)