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);
        }
示例#3
0
    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);
    }
示例#4
0
    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);
    }