Advent Of Code 2021 - Day 6

Day 6 is here, and this time it's about fish. We need to calculate how many lanternfish will spawn in a given number of days. There are a few set rules about how the lanternfish spawn:

  • Each lanternfish creates a new lanternfish every 7 days
  • A newly created lanternfish needs 2 extra days before it starts creating new fish of its own.
  • When a lanternfish has created a new fish, it starts a new 7 day cycle that ends with it creating another fish.

Our input will look something like this:

3,4,3,1,2

This represents five different fish, and the number of days until they create a new fish. 0 is also a valid number of days, so it's not until after day 0 a new fish is created and the number is reset.

So in short, after a fish has passed day 0, a new fish is created with a value of 8, and the existing fish is reset to a value of 6. Simple enough, right?

First, we parse our input:

var input = (await File.ReadAllLinesAsync("input.txt"))[0].Split(',').Select(int.Parse).ToArray();

Then, I was lucky enough when solving Part 1, that the solution actually works for Part 2 aswell. Since we don't get to see Part 2 until we've solved Part 1, we never know what the question might be. In this case, Part 1 and Part 2 both want to know how many fish exists after a certain amount of days, and since my solution takes the number of days as a parameter it can be used for both parts. Here's how I did it:

private static long AgeFish(IEnumerable<int> input, int days)
{
    var fishCount = new Dictionary<int, long>
    {
        {0, 0},
        {1, 0},
        {2, 0},
        {3, 0},
        {4, 0},
        {5, 0},
        {6, 0},
        {7, 0},
        {8, 0}
    };

    input.GroupBy(x => x).ToList().ForEach(x => fishCount[x.Key] = x.Count());

    for (var i = 0; i < days; i++)
    {
        long? tempVal = null;
        foreach (var key in fishCount.Keys.OrderByDescending(x => x))
        {
            var count = tempVal ?? fishCount[key];
            var newKey = key == 0 ? 6 : key - 1;

            if (key == 0)
            {
                fishCount[8] = count;
                fishCount[6] += count;
            }
            else
            {
                tempVal = fishCount[newKey];
                fishCount[newKey] = count;
            }
        }
    }

    return fishCount.Values.Sum();
}

First, I create a dictionary to keep track of the amount of fish on each day in the cycle. Then I take the number of existing fish (from our input) and add those to the dictionary. After that we move forward, day by day, and basically just move the fish count down by a step each day, with some special handling if a fish has reached day 0.

Simple enough, and it works for both parts :)

Article Series

Advent Of Code 2021