我正在与这个难题作斗争,我有一个类似于康威生活的小型递归程序。它有一组以 10x10 的网格排列的章鱼,每个章鱼的能级从 0 到 9。在解决这个难题的每一步中:
- 每条章鱼的能量等级增加1
- 如果章鱼的能量水平超过 9,它就会闪烁,即它的每个邻居都会获得一个能量增量。此增量可能导致邻居也闪烁。
- 任何闪光的章鱼都会将其能量重置为零。
Octopus[,] _octoGrid
根据拼图输入,我有一个二维数组,其中填充了不同能量水平的章鱼。我的Octopus
课看起来像这样:
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;
}
}
我驱动“游戏”步骤的主循环如下所示:
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();
}
}
}
在运行之前,网格中没有九个能级,经过一次迭代,所有能级递增,有几个九,意味着在下一次迭代中,有几只章鱼会闪烁。由于无限递归和堆栈溢出错误,闪烁的下一次迭代永远不会完成。
我很确定我错过了visited
递归到的每个相邻章鱼的某种标志或某些东西,但是添加一个像这样的简单标志阻止了溢出,但阻止了谜题输出,即 100 次迭代后的能量水平,从是正确的。我在递归中做错了什么?