/// <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); } } }
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); }
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); }