/// <summary> /// Add a <see cref="ConstraintHeader"/> connecting all the /// <see cref="PossibleValue"/>s at the given <paramref name="valueIndex"/> on the /// given <paramref name="squares"/>. Skips null squares, null possible values, and any /// possible values in a known state (i.e. dropped or selected). /// </summary> /// <param name="squares">The squares to add possible square values from.</param> /// <param name="valueIndex"> /// The value index of the possible value within the squares. /// </param> /// <param name="matrix">The matrix for the current puzzle being solved.</param> public static void AddConstraintHeadersForValueIndex( ReadOnlySpan <Square?> squares, int valueIndex, ExactCoverMatrix matrix) { var possibleSquares = new PossibleValue[squares.Length]; int numPossibleSquares = 0; for (int i = 0; i < squares.Length; i++) { Square?square = squares[i]; if (square is null) { continue; } PossibleValue?possibleSquare = square.GetPossibleValue(valueIndex); if (possibleSquare is null || possibleSquare.State != PossibleSquareState.UNKNOWN) { continue; } possibleSquares[numPossibleSquares++] = possibleSquare; } ConstraintHeader.CreateConnectedHeader( matrix, new ReadOnlySpan <PossibleValue>(possibleSquares, 0, numPossibleSquares)); }
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); }