public void Should_Return_Live_Neighbour_Count_For_Boundary_Location(int rowIndex, int colIndex, int expectedLiveCount) { // Arrange var cells = new List <List <Cell> > { new List <Cell> { new Cell(CellState.Alive), new Cell(CellState.Alive), new Cell(CellState.Dead) }, new List <Cell> { new Cell(CellState.Alive), new Cell(CellState.Dead), new Cell(CellState.Alive) }, new List <Cell> { new Cell(CellState.Dead), new Cell(CellState.Dead), new Cell(CellState.Dead) }, new List <Cell> { new Cell(CellState.Dead), new Cell(CellState.Dead), new Cell(CellState.Dead) } }; var target = new NeighbourCounter(cells); // Act var result = target.GetLiveNeighbourCount(rowIndex, colIndex); // Assert Assert.Equal(expectedLiveCount, result); }
public void Should_Get_Live_Neighbour_Count_For_Central_Location() { // Arrange var cells = new List <List <Cell> > { new List <Cell> { new Cell(CellState.Dead), new Cell(CellState.Dead), new Cell(CellState.Dead) }, new List <Cell> { new Cell(CellState.Alive), new Cell(CellState.Alive), new Cell(CellState.Alive) }, new List <Cell> { new Cell(CellState.Dead), new Cell(CellState.Dead), new Cell(CellState.Dead) } }; var target = new NeighbourCounter(cells); // Act var result = target.GetLiveNeighbourCount(1, 1); // Assert Assert.Equal(2, result); }
private static int SolvePart1(List <int> inputActiveCubes, int width, int height) { const int originZ = 0; int activeCubeCount = 0; int[] activeCubes = new int[(width + 12) * (height + 12) * 7]; foreach (int cube in inputActiveCubes) { activeCubes[activeCubeCount++] = cube + originZ * Z; } int[] nextActiveCubes = new int[activeCubes.Length]; var counter = new NeighbourCounter(activeCubes.Length, (originZ + 7) * Z); for (int iteration = 0; iteration < 6; iteration++) { counter.ResetNeighbours(); Span <int> activeCubesSpan = activeCubes.AsSpan().Slice(0, activeCubeCount); foreach (int cube in activeCubesSpan) { counter.UpdateNeighbourTotalsXYZ(cube); } int nextActiveCubesCount = 0; foreach (int cube in activeCubesSpan) { if (counter.GetNeighbourTotal(cube) is 3 or 4) { nextActiveCubes[nextActiveCubesCount++] = cube; counter.ResetNeighbourTotal(cube); // reset neighbour total for the cube so it doesn't get triggered by the next loop } } foreach (int cube in counter.Neighbours) { if (counter.GetNeighbourTotal(cube) == 3) { nextActiveCubes[nextActiveCubesCount++] = cube; } counter.ResetNeighbourTotal(cube); } activeCubes = nextActiveCubes; activeCubeCount = nextActiveCubesCount; } int totalCubeCount = 0; for (int i = 0; i < activeCubeCount; i++) { int cube = activeCubes[i]; int z = cube >> 10; if (z == 0) { totalCubeCount += 1; } else { totalCubeCount += 2; } } return(totalCubeCount); }
private static int SolvePart2(List <int> inputActiveCubes, int width, int height) { const int originZ = 0; const int originW = 0; int activeCubeCount = 0; int[] activeCubes = new int[(width + 12) * (height + 12) * 7 * 7]; foreach (int cube in inputActiveCubes) { activeCubes[activeCubeCount++] = cube + originZ * Z + originW * W; } int[] nextActiveCubes = new int[activeCubes.Length]; var counter = new NeighbourCounter(activeCubes.Length, (originW + 7) * W); for (int iteration = 0; iteration < 6; iteration++) { counter.ResetNeighbours(); Span <int> activeCubesSpan = activeCubes.AsSpan().Slice(0, activeCubeCount); foreach (int cube in activeCubesSpan) { counter.UpdateNeighbourTotalsXYZW(cube); } int nextActiveCubesCount = 0; foreach (int cube in activeCubesSpan) { if (counter.GetNeighbourTotal(cube) is 3 or 4) { nextActiveCubes[nextActiveCubesCount++] = cube; counter.ResetNeighbourTotal(cube); // reset neighbour total for the cube so it doesn't get triggered by the next loop } } foreach (int cube in counter.Neighbours) { if (counter.GetNeighbourTotal(cube) == 3) { nextActiveCubes[nextActiveCubesCount++] = cube; } counter.ResetNeighbourTotal(cube); } activeCubes = nextActiveCubes; activeCubeCount = nextActiveCubesCount; } int zwPlane = 0; int wAxis = 0; int wzAxis = 0; int other = 0; for (int i = 0; i < activeCubeCount; i++) { int cube = activeCubes[i]; int z = (cube >> 10) & 0b111; int w = cube >> 13; if (z == 0 && w == 0) { zwPlane++; } else if (w == 0) { wAxis++; } else if (w == z) { wzAxis++; } else { other++; } } return(zwPlane + 4 * wAxis + 4 * wzAxis + 8 * other); }