0

I am battling with this puzzle where I have a small, recursive program that is sort of similar to Conway's life. It has a set of octopuses arranged in a 10x10 grid, and each one has an energy level from 0 to 9. During each step of solving this puzzle:

  • The energy level of each octopus increases by 1
  • If an octopuses energy level exceeds 9, it Flashes, i.e. each of its neighbours gets an energy increment. This increment can cause a neighbour to also Flash.
  • Any octopuses that flashed have their energy reset to zero.

I have a 2-dimensional array, Octopus[,] _octoGrid which is populated with octopuses of varying energy levels, according to the puzzle input. My Octopus class looks like this:

private class Octopus
{
    public int Y { get; }

    public int X { get; }

    public int Energy { get; set; }

    public bool HasFlashed { get; set; } = false;

    public Octopus(int y, int x, int energy)
    {
        Y = y;
        X = x;
        Energy = energy;
    }

    public static IEnumerable<Octopus> NeighbouringOctopuses(Octopus[,] array, int row, int column)
    {
        int rows = array.GetLength(0);
        int columns = array.GetLength(1);

        for (int y = row - 1; y <= row + 1; y++)
            for (int x = column - 1; x <= column + 1; x++)
                if (x >= 0 && y >= 0 && x < columns && y < rows && !(y == row && x == column))
                {
                    var oct = array[y, x];
                    yield return array[y, x];
                }
    }

    public override string ToString()
    {
        return $"{Y},{X}: {Energy}";
    }

    internal void CheckForFlash()
    {
        Energy++;
        if (Energy > 9 && !HasFlashed) Flash();
    }

    internal void Flash()
    {
        var neighbours = NeighbouringOctopuses(_octoGrid, Y, X);
        foreach (var neighbour in neighbours)
            neighbour.CheckForFlash();

        HasFlashed = true;
        Energy = 0;
        _flashCount += 1;
    }
}

and my main loop driving the 'game' steps looks like this:

for (int i = 0; i < 100; i++)
{
    for (int y = 0; y < _octoGrid.GetLength(0); y++)
    {
        for (int x = 0; x < _octoGrid.GetLength(1); x++)
        {
            var octo = _octoGrid[y, x];
            octo.CheckForFlash();
        }
    }
}

Before running this, there are no nine energy levels in the grid, and after one iteration and all energy levels incrementing, there are a few nines, meaning that in the next iteration, several octopuses will Flash. The next iteration, with the flashes, never completes due to infinite recursion and a stack overflow error.

I'm quite certain I'm missing some sort of visited flag or something for each neighbouring octopus that gets recursed into, but adding a simple flag like that stopped the overflow, but prevented the puzzle output, i.e. the energy levels after 100 iterations, from being correct. What am I doing wrong in my recursion?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
ProfK
  • 49,207
  • 121
  • 399
  • 775
  • Advent-of-code is an annual advent calendar of daily coding puzzles. I thought I'd add the tag as someone who has not yet attempted the puzzle I posted about might find the code I posted to be a spoiler, even if it is wrong. – ProfK Dec 16 '21 at 19:27
  • You should post a link to the challenge description. (i.e. is recursion a must?) – aybe Dec 16 '21 at 19:29
  • @aybe I have made the words `this puzzle` a hyperlink to the puzzle, Recursion certainly isn't a must, in fact code isn't even a must - you could very well solve the puzzle with Excel if you're capable. – ProfK Dec 16 '21 at 20:07
  • I think you should set `HasFlashed` before the `neighbour.CheckForFlash()` loop. – 500 - Internal Server Error Dec 16 '21 at 22:15
  • @500-InternalServerError Thank you, that seems to have fixed my recursion. My puzzle output is still not correct but that's a whole other matter. Cheers. – ProfK Dec 16 '21 at 22:32
  • I would discover neighbouring from the main loop only when the current octopus HasFlashed is true. While checking for flash the neighbouring, you must skip all octopus that have already flashed, else the examples from the puzzle wouldn't match. – Hazrelle Dec 16 '21 at 23:13

0 Answers0