diff --git a/2021/README.md b/2021/README.md index 4d4b08f..4c6bcfc 100644 --- a/2021/README.md +++ b/2021/README.md @@ -15,7 +15,7 @@ | S | M | T | W | T | F | S | | :-: | :-: | :-: | :-: | :-: | :-: | :-: | | | | | [1] | [2] | [3] | [4] | -| [5] | 6 | 7 | 8 | 9 | 10 | 11 | +| [5] | [6] | 7 | 8 | 9 | 10 | 11 | | 12 | 13 | 14 | 15 | 16 | 17 | 18 | | 19 | 20 | 21 | 22 | 23 | 24 | 25 | @@ -26,3 +26,4 @@ [3]: ./lib/2021/3.ex [4]: ./lib/2021/4.ex [5]: ./lib/2021/5.ex +[6]: ./lib/2021/6.ex diff --git a/2021/lib/2021/6.ex b/2021/lib/2021/6.ex new file mode 100644 index 0000000..e5d287a --- /dev/null +++ b/2021/lib/2021/6.ex @@ -0,0 +1,47 @@ +import AOC + +aoc 2021, 6 do + use AOCHelpers + + @doc """ + Emulates the fish literally as described by the problem but + adds new (starting at 8) fish next to their parent instead + of at the end of list. + """ + def tick_literal([]), do: [] + def tick_literal([0 | xs]), do: [6, 8 | tick_literal(xs)] + def tick_literal([x | xs]), do: [x - 1 | tick_literal(xs)] + + @doc """ + "Ticks" a day-frequency encoded list of fish counts to the next day. + + Formula for the next-day count: + fish(8) = fish(0) + fish(6) = fish(7) + fish(0) + fish(n) = fish(n + 1) + """ + def tick_encoded([f0, f1, f2, f3, f4, f5, f6, f7, f8]) do + # 0, 1, 2, 3, 4, 5, 6, 7, 8 + [f1, f2, f3, f4, f5, f6, f7 + f0, f8, f0] + end + + def p1 do + start = input_number_list() + + iterate(80, start, &tick_literal/1) + |> length() + end + + def p2 do + start = input_number_list() + + freqs = + start + |> Enum.frequencies() + + encoded_fish = for i <- 0..8, do: Map.get(freqs, i, 0) + + iterate(256, encoded_fish, &tick_encoded/1) + |> Enum.sum() + end +end diff --git a/2021/lib/AOCHelpers.ex b/2021/lib/AOCHelpers.ex new file mode 100644 index 0000000..5666ee9 --- /dev/null +++ b/2021/lib/AOCHelpers.ex @@ -0,0 +1,16 @@ +defmodule AOCHelpers do + defmacro __using__(_) do + quote do + def input_number_list(sep \\ ",") do + input_string() + |> String.trim() + |> String.split(sep) + |> Enum.map(&String.to_integer/1) + end + + def iterate(times, start, fun) do + Enum.reduce(1..times, start, fn _, current -> fun.(current) end) + end + end + end +end