/// <inheritdoc/>
        public void Constrain(IReadOnlyPuzzle puzzle, ExactCoverMatrix matrix)
        {
            Span <bool> isConstraintSatisfiedAtIndex =
                stackalloc bool[matrix.AllPossibleValues.Length];

            for (int row = 0; row < puzzle.Size; row++)
            {
                ReadOnlySpan <Square?> rowSquares = matrix.GetSquaresOnRow(row);
                isConstraintSatisfiedAtIndex.Clear();
                for (int col = 0; col < puzzle.Size; col++)
                {
                    int?puzzleValue = puzzle[row, col];
                    if (puzzleValue.HasValue)
                    {
                        isConstraintSatisfiedAtIndex[matrix.ValuesToIndices[puzzleValue.Value]] = true;
                    }
                }
                for (int valueIndex = 0; valueIndex < isConstraintSatisfiedAtIndex.Length; valueIndex++)
                {
                    if (isConstraintSatisfiedAtIndex[valueIndex])
                    {
                        ConstraintUtil.DropPossibleSquaresForValueIndex(rowSquares, valueIndex, matrix);
                        continue;
                    }
                    ConstraintUtil.AddConstraintHeadersForValueIndex(rowSquares, valueIndex, matrix);
                }
            }
        }
Пример #2
0
        private static void _ConstrainBackwardDiagonal(IReadOnlyPuzzle puzzle, ExactCoverMatrix matrix)
        {
            Span <Coordinate> Coordinates = stackalloc Coordinate[puzzle.Size];

            for (int row = 0, col = 0; row < puzzle.Size; row++, col++)
            {
                Coordinates[row] = new Coordinate(row, col);
            }
            ConstraintUtil.ImplementUniquenessConstraintForSquares(puzzle, Coordinates, matrix);
        }
        private static bool _TryConstrainBackwardDiagonal(IReadOnlyPuzzle puzzle, ExactCoverGraph graph)
        {
            Span <Coordinate> Coordinates = stackalloc Coordinate[puzzle.Size];

            for (int row = 0, col = 0; row < puzzle.Size; row++, col++)
            {
                Coordinates[row] = new Coordinate(row, col);
            }
            return(ConstraintUtil.TryImplementUniquenessConstraintForSquares(puzzle, Coordinates, graph));
        }
        /// <inheritdoc/>
        public void Constrain(IReadOnlyPuzzle puzzle, ExactCoverMatrix matrix)
        {
            Span <Coordinate> columnCoordinates = stackalloc Coordinate[puzzle.Size];

            for (int column = 0; column < puzzle.Size; column++)
            {
                for (int row = 0; row < puzzle.Size; row++)
                {
                    columnCoordinates[row] = new Coordinate(row, column);
                }
                ConstraintUtil.ImplementUniquenessConstraintForSquares(puzzle, columnCoordinates, matrix);
            }
        }
Пример #5
0
        /// <inheritdoc/>
        public bool TryConstrain(IReadOnlyPuzzle puzzle, ExactCoverGraph graph)
        {
            Span <Coordinate> columnCoordinates = stackalloc Coordinate[puzzle.Size];

            for (int column = 0; column < puzzle.Size; column++)
            {
                for (int row = 0; row < puzzle.Size; row++)
                {
                    columnCoordinates[row] = new Coordinate(row, column);
                }
                if (!ConstraintUtil.TryImplementUniquenessConstraintForSquares(puzzle, columnCoordinates, graph))
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #6
0
        private static bool _TryAppendRequirementsInBox(
            int box, int boxSize, IReadOnlyPuzzle puzzle, ExactCoverGraph graph)
        {
            Coordinate startCoord = Boxes.GetStartingBoxCoordinate(box, boxSize);
            var        endCoord   = new Coordinate(
                startCoord.Row + boxSize, startCoord.Column + boxSize);
            Span <Coordinate> boxCoordinates = stackalloc Coordinate[puzzle.Size];
            int i = 0;

            for (int row = startCoord.Row; row < endCoord.Row; row++)
            {
                for (int col = startCoord.Column; col < endCoord.Column; col++)
                {
                    boxCoordinates[i++] = new Coordinate(row, col);
                }
            }
            return(ConstraintUtil.TryImplementUniquenessConstraintForSquares(puzzle, boxCoordinates, graph));
        }
Пример #7
0
        private static void _AppendConstraintHeadersInBox(
            int box, IReadOnlyBoxPuzzle puzzle, ExactCoverMatrix matrix)
        {
            Coordinate startCoord = puzzle.GetStartingBoxCoordinate(box);
            var        endCoord   = new Coordinate(
                startCoord.Row + puzzle.BoxSize, startCoord.Column + puzzle.BoxSize);
            Span <Coordinate> boxCoordinates = stackalloc Coordinate[puzzle.Size];
            int i = 0;

            for (int row = startCoord.Row; row < endCoord.Row; row++)
            {
                for (int col = startCoord.Column; col < endCoord.Column; col++)
                {
                    boxCoordinates[i++] = new Coordinate(row, col);
                }
            }
            ConstraintUtil.ImplementUniquenessConstraintForSquares(puzzle, boxCoordinates, matrix);
        }
Пример #8
0
        /// <inheritdoc/>
        public bool TryConstrain(IReadOnlyPuzzle puzzle, ExactCoverGraph graph)
        {
            Span <bool> isConstraintSatisfiedAtIndex =
                stackalloc bool[graph.AllPossibleValues.Length];

            for (int row = 0; row < puzzle.Size; row++)
            {
                ReadOnlySpan <Possibility?[]?> rowSquares = graph.GetPossibilitiesOnRow(row);
                isConstraintSatisfiedAtIndex.Clear();
                for (int col = 0; col < puzzle.Size; col++)
                {
                    int?puzzleValue = puzzle[row, col];
                    if (puzzleValue.HasValue)
                    {
                        int valueIndex = graph.ValuesToIndices[puzzleValue.Value];
                        if (isConstraintSatisfiedAtIndex[valueIndex])
                        {
                            return(false);
                        }
                        isConstraintSatisfiedAtIndex[valueIndex] = true;
                    }
                }
                for (int possibilityIndex = 0; possibilityIndex < isConstraintSatisfiedAtIndex.Length; possibilityIndex++)
                {
                    if (isConstraintSatisfiedAtIndex[possibilityIndex])
                    {
                        if (!ConstraintUtil.TryDropPossibilitiesAtIndex(rowSquares, possibilityIndex))
                        {
                            return(false);
                        }
                        continue;
                    }
                    if (!ConstraintUtil.TryAddObjectiveForPossibilityIndex(
                            rowSquares, possibilityIndex, graph, requiredCount: 1, objective: out _))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }