|  | 
|  | 1 | +ExUnit.start() | 
|  | 2 | + | 
|  | 3 | +defmodule Lanternfish do | 
|  | 4 | + def load_file() do | 
|  | 5 | + File.read!("../input.txt") | 
|  | 6 | + |> String.split(",", trim: true) | 
|  | 7 | + end | 
|  | 8 | + | 
|  | 9 | + def parse_swarm(input) do | 
|  | 10 | + input | 
|  | 11 | + |> Enum.group_by(& &1) | 
|  | 12 | + |> Enum.map(fn {i, vals} -> {i, Enum.count(vals)} end) | 
|  | 13 | + |> Map.new() | 
|  | 14 | + end | 
|  | 15 | + | 
|  | 16 | + def give_offspring(fish, 0) do | 
|  | 17 | + fish |> Map.delete(9) | 
|  | 18 | + end | 
|  | 19 | + | 
|  | 20 | + def give_offspring(fish, days_remaining) do | 
|  | 21 | + safe_fish = | 
|  | 22 | + fish | 
|  | 23 | + |> Map.put_new(0, 0) | 
|  | 24 | + |> Map.put_new(1, 0) | 
|  | 25 | + |> Map.put_new(2, 0) | 
|  | 26 | + |> Map.put_new(3, 0) | 
|  | 27 | + |> Map.put_new(4, 0) | 
|  | 28 | + |> Map.put_new(5, 0) | 
|  | 29 | + |> Map.put_new(6, 0) | 
|  | 30 | + |> Map.put_new(7, 0) | 
|  | 31 | + |> Map.put_new(8, 0) | 
|  | 32 | + |> Map.put_new(9, 0) | 
|  | 33 | + | 
|  | 34 | + safe_fish | 
|  | 35 | + |> Map.put(7, safe_fish[7] + safe_fish[0]) | 
|  | 36 | + |> Map.put(9, safe_fish[9] + safe_fish[0]) | 
|  | 37 | + |> Enum.map(fn {internal_counter, amount} -> {internal_counter - 1, amount} end) | 
|  | 38 | + |> Map.new() | 
|  | 39 | + |> Map.delete(-1) | 
|  | 40 | + |> Map.delete(9) | 
|  | 41 | + |> give_offspring(days_remaining - 1) | 
|  | 42 | + end | 
|  | 43 | + | 
|  | 44 | + def solve(days) do | 
|  | 45 | + fish = | 
|  | 46 | + load_file() | 
|  | 47 | + |> Enum.map(&Integer.parse/1) | 
|  | 48 | + |> Enum.map(&elem(&1, 0)) | 
|  | 49 | + |> parse_swarm() | 
|  | 50 | + |> give_offspring(days) | 
|  | 51 | + | 
|  | 52 | + Enum.map(fish, fn {_, amount} -> amount end) | 
|  | 53 | + |> Enum.sum() | 
|  | 54 | + end | 
|  | 55 | + | 
|  | 56 | + @spec first() :: Integer | 
|  | 57 | + def first() do | 
|  | 58 | + solve(80) | 
|  | 59 | + end | 
|  | 60 | + | 
|  | 61 | + @spec second() :: Integer | 
|  | 62 | + def second() do | 
|  | 63 | + solve(256) | 
|  | 64 | + end | 
|  | 65 | +end | 
|  | 66 | + | 
|  | 67 | +defmodule LanternfishTest do | 
|  | 68 | + use ExUnit.Case | 
|  | 69 | + | 
|  | 70 | + describe "giveOffsprint/2" do | 
|  | 71 | + test "Initial value" do | 
|  | 72 | + swarm = Lanternfish.parse_swarm([3, 4, 3, 1, 2]) | 
|  | 73 | + assert Lanternfish.give_offspring(swarm, 0) == %{1 => 1, 2 => 1, 3 => 2, 4 => 1} | 
|  | 74 | + end | 
|  | 75 | + | 
|  | 76 | + test "After 1 day" do | 
|  | 77 | + swarm = Lanternfish.parse_swarm([3, 4, 3, 1, 2]) | 
|  | 78 | + | 
|  | 79 | + assert Lanternfish.give_offspring(swarm, 1) == %{ | 
|  | 80 | + 0 => 1, | 
|  | 81 | + 1 => 1, | 
|  | 82 | + 2 => 2, | 
|  | 83 | + 3 => 1, | 
|  | 84 | + 4 => 0, | 
|  | 85 | + 5 => 0, | 
|  | 86 | + 6 => 0, | 
|  | 87 | + 7 => 0, | 
|  | 88 | + 8 => 0 | 
|  | 89 | + } | 
|  | 90 | + end | 
|  | 91 | + | 
|  | 92 | + test "After 2 days" do | 
|  | 93 | + swarm = Lanternfish.parse_swarm([3, 4, 3, 1, 2]) | 
|  | 94 | + | 
|  | 95 | + assert Lanternfish.give_offspring(swarm, 2) == %{ | 
|  | 96 | + 0 => 1, | 
|  | 97 | + 1 => 2, | 
|  | 98 | + 2 => 1, | 
|  | 99 | + 3 => 0, | 
|  | 100 | + 4 => 0, | 
|  | 101 | + 5 => 0, | 
|  | 102 | + 6 => 1, | 
|  | 103 | + 7 => 0, | 
|  | 104 | + 8 => 1 | 
|  | 105 | + } | 
|  | 106 | + end | 
|  | 107 | + end | 
|  | 108 | +end | 
0 commit comments