diff options
Diffstat (limited to '2021/day-06/day-06.livemd')
-rw-r--r-- | 2021/day-06/day-06.livemd | 152 |
1 files changed, 0 insertions, 152 deletions
diff --git a/2021/day-06/day-06.livemd b/2021/day-06/day-06.livemd deleted file mode 100644 index 5ab794f..0000000 --- a/2021/day-06/day-06.livemd +++ /dev/null @@ -1,152 +0,0 @@ -<!-- vim: set syntax=markdown: --> -<!-- livebook:{"persist_outputs":true} --> - -# Advent of Code 2021, Day 6 - -## Short problem summary - -A school of fish reproduce according to the following rules: - -* Every fish has an "internal timer" -* The timer decrements by one every day -* If the timer is at 0, the timer is instead reset to 6, - and a new fish with an internal timer of 8 is added to the school - -Questions: - -1. How many fish are in the school after 80 days? -2. How many fish are in the school after 256 days? - -## Setting up - -The initial input is a list of fish, represented by the initial value of their internal timer: - -```elixir -school = - with {:ok, data} <- File.read("day-06/input.txt") do - data - |> String.trim() - |> String.split(",") - |> Enum.map(&String.to_integer/1) - end -``` - -```output -[5, 4, 3, 5, 1, 1, 2, 1, 2, 1, 3, 2, 3, 4, 5, 1, 2, 4, 3, 2, 5, 1, 4, 2, 1, 1, 2, 5, 4, 4, 4, 1, 5, - 4, 5, 2, 1, 2, 5, 5, 4, 1, 3, 1, 4, 2, 4, 2, 5, 1, ...] -``` - -Every fish with the same starting internal timer will reproduce at the same time, -as will all of the children of those fish and their children, and so forth, -so we don't need to track individual fish; we just need to group the fish based on -their starting internal timer and track those groups throughout the simulation. - -```elixir -starting_state = Enum.frequencies(school) -``` - -```output -%{1 => 88, 2 => 45, 3 => 54, 4 => 52, 5 => 61} -``` - -Every time a day passes, the following things happen: - -* All the internal timers decrement by 1 -* The group of fish with an internal timer of -1 is reset to 6 - (added to any existing fish whose timers are already at 6), - and an equal-sized group of fish with internal timer 8 is added - -```elixir -defmodule Day06 do - def next_day(state) do - with one_day_older <- Enum.into(state, %{}, fn {k, v} -> {k - 1, v} end), - {n, s} <- Map.pop(one_day_older, -1, 0) do - Map.update(s, 6, n, &(&1 + n)) - |> Map.put(8, n) - end - end -end - -day1 = Day06.next_day(starting_state) -``` - -```output -%{0 => 88, 1 => 45, 2 => 54, 3 => 52, 4 => 61, 6 => 0, 8 => 0} -``` - -After the first day there's not any fish old enough to reproduce yet, but after the second day, - -```elixir -day2 = Day06.next_day(day1) -``` - -```output -%{0 => 45, 1 => 54, 2 => 52, 3 => 61, 5 => 0, 6 => 88, 7 => 0, 8 => 88} -``` - -The 88 fish whose timers were at 0 have rolled over to 6 and created 88 more fish with timers at 8. - -## Solution - -Now we just need to apply the transformation function the necessary number -of times and sum up the total population in the end: - -```elixir -part1_state = - Enum.reduce( - Enum.to_list(1..80), - starting_state, - fn _, acc -> Day06.next_day(acc) end - ) - |> IO.inspect() - |> Enum.reduce(0, fn {_, v}, acc -> v + acc end) -``` - -```output -%{ - 0 => 24572, - 1 => 43660, - 2 => 30525, - 3 => 48458, - 4 => 41318, - 5 => 47697, - 6 => 57731, - 7 => 23218, - 8 => 33738 -} -``` - -```output -350917 -``` - -Identically for part 2, - -```elixir -part2_state = - Enum.reduce( - Enum.to_list(1..256), - starting_state, - fn _, acc -> Day06.next_day(acc) end - ) - |> IO.inspect() - |> Enum.reduce(0, fn {_, v}, acc -> v + acc end) -``` - -```output -%{ - 0 => 139170477178, - 1 => 162618979933, - 2 => 169389497028, - 3 => 188231720546, - 4 => 207908029672, - 5 => 217769615201, - 6 => 252681772250, - 7 => 117023886952, - 8 => 138124736869 -} -``` - -```output -1592918715629 -``` |