bjorng
Advent of Code 2021 - Day 6
This topic is about Day 6 of the Advent of Code 2021.
We have a private leaderboard (shared with users of Erlang Forums ):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Most Liked
ruslandoga
I went with representing the frequencies as a tuple and a simulation step was:
defp simulate({s0, s1, s2, s3, s4, s5, s6, s7, s8}, days) when days > 0 do
simulate({s1, s2, s3, s4, s5, s6, s7 + s0, s8, s0}, days - 1)
end
It’d be nice to see an Nx solution here, it fits this problem very nicely.
wasi0013
I enjoyed this one! 
defmodule Aoc.Y2021.Day06 do
@moduledoc """
Solved https://adventofcode.com/2021/day/6
"""
import Aoc.Helper.IO
def run_part1(), do: get_input() |> solve_part1()
def run_part2(), do: get_input() |> solve_part2()
def solve_part1(data), do: solve(data, 80)
def solve_part2(data), do: solve(data, 256)
def solve(data, days), do: data |> fish_count() |> simulate(days) |> Enum.sum()
def fish_count(data), do: Enum.map(0..8, fn n -> Map.get(Enum.frequencies(data), n, 0) end)
def simulate(fish_count, 0), do: fish_count
def simulate([zeroth, first, second, third, fourth, fifth, sixth, seventh, eighth], days) do
simulate([first, second, third, fourth, fifth, sixth, seventh + zeroth, eighth, zeroth], days - 1)
end
defp get_input(), do: get_integer_input("2021", "06", ",")
end
jarimatti
I think there is an elegant mathematical way, using linear algebra: the amount of fish that have specific day can be modeled as a vector, where element 0 is the amount of fish that have 0 days left. Total number of fish at any given day is the sum of elements of that vector.
We can multiply that vector with a matrix K, that produces the next day’s fish counts. Here’s what K could look like (apologies for Octave/Matlab syntax, I used that to verify the approach):
K0 = [
0 0 0 0 0 0 1 0 1;
1 0 0 0 0 0 0 0 0;
0 1 0 0 0 0 0 0 0;
0 0 1 0 0 0 0 0 0;
0 0 0 1 0 0 0 0 0;
0 0 0 0 1 0 0 0 0;
0 0 0 0 0 1 0 0 0;
0 0 0 0 0 0 1 0 0;
0 0 0 0 0 0 0 1 0
];
# Fun fact: matrix for computing any initial condition to day 80 is:
K80 = K0 ^ 80;
# Get day 1 from day 0 counts per day:
v1 = v0 * K;
# Get day 80 from day 0 counts per day:
v80 = v0 * K80;
Full code here for my input: aoc2021_day6.m
I’ve yet to figure out how to do this in Elixir fluently and it seems it’s time to learn some Nx. 
jarimatti
OK, that was more fun than expected. (pun not intended)
Nx solution module over here: Aoc2021.Day6.LinAlg
Nx multiply and especially Nx.power are done by element, so I had to resort to reduce when multiplying the tensors. Otherwise it pretty much follows the Octave style. I like Nx so far, this was easy to install and play around with.
qhwa
Thank you for sharing this! This matrix is awesome!
I watched @josevalim 's video on day 6, and oh man, it was so amazing and blew my mind. In the end, he tried the same matrix idea with Nx. It was so delightful to watch him thinking, solving, and explaining.







