/// <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);
                }
            }
        }
Example #2
0
        public void TryRemoveFromConstraint_OnSuccess()
        {
            var puzzle           = new Puzzle(4);
            var matrix           = new ExactCoverMatrix(puzzle);
            var constraintHeader = ConstraintHeader.CreateConnectedHeader(
                matrix,
                matrix.GetSquaresOnRow(0).ToArray().Select(s => s.AllPossibleValues[0]).ToArray());
            Link firstLink  = constraintHeader.FirstLink;
            Link secondLink = firstLink.Down;
            Link thirdLink  = secondLink.Down;
            Link fourthLink = thirdLink.Down;

            Assert.True(firstLink.TryRemoveFromConstraint());

            Assert.Same(fourthLink, firstLink.Up);
            Assert.Same(secondLink, firstLink.Down);
            Assert.Same(secondLink, constraintHeader.FirstLink);
            Assert.Same(fourthLink, secondLink.Up);
            Assert.Same(secondLink, fourthLink.Down);
            Assert.Equal(3, constraintHeader.Count);
        }
Example #3
0
        public void TryRemoveFromConstraint_WhenConstraintSatisfied_LeavesUnchanged()
        {
            var puzzle           = new Puzzle(4);
            var matrix           = new ExactCoverMatrix(puzzle);
            var constraintHeader = ConstraintHeader.CreateConnectedHeader(
                matrix,
                matrix.GetSquaresOnRow(0).ToArray().Select(s => s.AllPossibleValues[0]).ToArray());
            Link firstLink  = constraintHeader.FirstLink;
            Link secondLink = firstLink.Down;
            Link thirdLink  = secondLink.Down;
            Link fourthLink = thirdLink.Down;
            int  expectedConstraintCount = constraintHeader.Count;

            Assert.True(firstLink.TrySatisfyConstraint());
            Assert.True(secondLink.TryRemoveFromConstraint());

            Assert.Equal(expectedConstraintCount, constraintHeader.Count);
            Assert.Same(firstLink, secondLink.Up);
            Assert.Same(secondLink, firstLink.Down);
            Assert.Same(secondLink, thirdLink.Up);
            Assert.Same(thirdLink, secondLink.Down);
        }