public void Constrain_GroupsConstraintsAsExpected() { int size = 4; int boxSize = 2; int[] possibleValues = new int[] { 1, 3, 5, 7 }; var puzzle = new Puzzle(size); var matrix = ExactCoverGraph.Create(puzzle); var squareObjectives = new HashSet <Objective>(matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities()); Assert.True(new BoxUniquenessConstraint().TryConstrain(puzzle, matrix)); Assert.Equal( size * possibleValues.Length + squareObjectives.Count, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Count()); Dictionary <int, HashSet <int> > boxIndicesToValues = new(); for (int i = 0; i < size; ++i) { boxIndicesToValues[i] = new HashSet <int>(); } Assert.All(matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities(), concreteObjective => { if (squareObjectives.Contains(concreteObjective)) { return; } IObjective objective = concreteObjective; var possibilities = objective.GetUnknownDirectPossibilities().Cast <Possibility>().ToArray(); int boxIndex = Boxes.CalculateBoxIndex(possibilities[0].Coordinate, boxSize); int value = possibilities[0].Index; Assert.DoesNotContain(value, boxIndicesToValues[boxIndex]); boxIndicesToValues[boxIndex].Add(value); var boxCoordinates = Boxes.YieldUnsetCoordsForBox(boxIndex, boxSize, puzzle).ToArray(); Assert.Equal(boxCoordinates.Length, possibilities.Length); Assert.All(possibilities, p => { Assert.Contains(p.Coordinate, boxCoordinates); Assert.Equal(value, p.Index); }); Assert.All(boxCoordinates, c => Assert.NotNull(possibilities.SingleOrDefault(p => p.Coordinate == c))); }); Assert.All( boxIndicesToValues.Values, values => Assert.Equal(new HashSet <int> { 0, 1, 2, 3 }, values)); }
public void YieldUnsetForBox_ReturnsAllUnsetCoordsInBox() { var puzzle = new Puzzle(new int?[][] { new int?[] { 1, null, null, 2 }, new int?[] { null, null, 1, null }, new int?[] { null, 1, null, null }, new int?[] { 3, null, 4, null } }); int box = 1; var allUnset = new List <Coordinate>(Boxes.YieldUnsetCoordsForBox(box, boxSize: 2, puzzle: puzzle)); Assert.Equal(2, allUnset.Count); Assert.Equal(new HashSet <Coordinate> { new(0, 2), new(1, 3) }, new HashSet <Coordinate>(allUnset));
/// <inheritdoc/> public bool UpdateAll() { Debug.Assert( _puzzle is not null && _helper is not null, $"Must initialize heuristic before calling {nameof(UpdateAll)}."); int size = _puzzle.Size; var possibleValuesToCheck = new BitVector[size]; var coordinatesToCheck = new Coordinate[size][]; for (int boxIdx = 0; boxIdx < size; ++boxIdx) { possibleValuesToCheck[boxIdx] = _boxTracker.GetMissingValuesForBox(boxIdx); coordinatesToCheck[boxIdx] = Boxes.YieldUnsetCoordsForBox(boxIdx, _boxSize, _puzzle).ToArray(); } return(_helper.UpdateIfUnique(possibleValuesToCheck, coordinatesToCheck)); }