<!-- vim: syntax=markdown -->
# Advent 2021 - Day 6
## Setup
```elixir
Mix.install([
{:vega_lite, "~> 0.1.2"},
{:kino, github: "livebook-dev/kino"}
])
```
```elixir
alias VegaLite, as: Vl
```
```elixir
input = Kino.Input.textarea("Please paste your input file:")
```
```elixir
initial_lanternfish =
input
|> Kino.Input.read()
|> String.trim()
|> String.split(",")
|> Enum.map(&String.to_integer(&1))
|> Enum.reduce(%{}, fn lanternfish, acc ->
Map.get_and_update(acc, lanternfish, fn val ->
next_val = if val == nil, do: 1, else: val + 1
{val, next_val}
end)
|> elem(1)
end)
```
## Utils
```elixir
defmodule Utils do
def sum_lanternfish(lanternfish) do
lanternfish |> Map.values() |> Enum.sum()
end
def grow_lanternfish(_widget, lanternfish, days) when days == 0 do
lanternfish
end
def grow_lanternfish(widget, lanternfish, days) do
lanternfish =
lanternfish
|> Enum.map(fn {k, v} -> {k - 1, v} end)
|> Enum.into(%{})
lanternfish =
if Map.has_key?(lanternfish, -1) do
refresh_count = Map.get(lanternfish, -1)
lanternfish
|> Map.drop([-1])
|> Map.update(6, refresh_count, &(&1 + refresh_count))
|> Map.update(8, refresh_count, &(&1 + refresh_count))
else
lanternfish
end
data = %{"day" => floor(days * -1), "number of fish" => sum_lanternfish(lanternfish)}
Kino.VegaLite.push(widget, data, window: 40)
Process.sleep(25)
grow_lanternfish(widget, lanternfish, days - 1)
end
end
```
## Part 1
```elixir
part1_widget =
Vl.new(width: 800, height: 300)
|> Vl.mark(:bar)
|> Vl.encode_field(:x, "day", type: :temporal)
|> Vl.encode_field(:y, "number of fish", type: :quantitative)
|> Kino.VegaLite.new()
```
```elixir
Utils.grow_lanternfish(part1_widget, initial_lanternfish, 80) |> Utils.sum_lanternfish()
```
## Part 2
```elixir
part2_widget =
Vl.new(width: 800, height: 300)
|> Vl.mark(:bar)
|> Vl.encode_field(:x, "day", type: :temporal)
|> Vl.encode_field(:y, "number of fish", type: :quantitative)
|> Kino.VegaLite.new()
```
```elixir
Utils.grow_lanternfish(part2_widget, initial_lanternfish, 256) |> Utils.sum_lanternfish()
```