Esempio n. 1
0
        public void TrySelectAndDeselectPossibility_WithMultipleRequired_Works()
        {
            var puzzle        = new Puzzle(4);
            var matrix        = ExactCoverGraph.Create(puzzle);
            var possibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var        firstSelected     = possibilities[0];
            var        secondSelected    = possibilities[1];
            var        concreteObjective = Objective.CreateFullyConnected(matrix, possibilities, 2);
            IObjective objective         = concreteObjective;

            Assert.True(objective.TrySelectPossibility(firstSelected.AttachedObjectives.First()));
            Assert.NotEqual(NodeState.SELECTED, concreteObjective.State);
            Assert.Equal(1, concreteObjective.CountUnknown);
            Assert.Single(objective.GetUnknownDirectPossibilities(), secondSelected);
            Assert.Contains(concreteObjective, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());

            Assert.True(objective.TrySelectPossibility(secondSelected.AttachedObjectives.First()));
            Assert.Equal(NodeState.SELECTED, concreteObjective.State);
            Assert.Equal(0, concreteObjective.CountUnknown);
            Assert.True(!matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Contains(concreteObjective) ||
                        matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Count() == 1);

            objective.DeselectPossibility(secondSelected.AttachedObjectives.First());
            Assert.NotEqual(NodeState.SELECTED, concreteObjective.State);
            Assert.Equal(1, concreteObjective.CountUnknown);
            Assert.Single(objective.GetUnknownDirectPossibilities(), secondSelected);
            Assert.Contains(concreteObjective, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());

            objective.DeselectPossibility(firstSelected.AttachedObjectives.First());
            Assert.Equal(2, concreteObjective.CountUnknown);
        }
Esempio n. 2
0
        public void Create_ConfiguresSquareObjectives()
        {
            var puzzle = new Puzzle(4);
            var graph  = ExactCoverGraph.Create(puzzle);

            var objectives = graph.GetUnsatisfiedRequiredObjectives();

            Assert.Equal(puzzle.Size * puzzle.Size, objectives.Count());

            var seenCoordinates    = new HashSet <Coordinate>();
            var possibilityIndices = new HashSet <int>()
            {
                0, 1, 2, 3
            };

            Assert.All(objectives,
                       concreteObjective =>
            {
                IObjective objective = concreteObjective;
                var possibilities    = objective.GetUnknownDirectPossibilities().Cast <Possibility>().ToArray();
                // Assert that each square links every possibility at that coordinate.
                Assert.Equal(puzzle.Size, possibilities.Length);
                Assert.Equal(possibilityIndices, new HashSet <int>(possibilities.Select(p => p.Index)));
                var firstCoord = possibilities.First().Coordinate;
                Assert.All(possibilities,
                           p =>
                {
                    Assert.Equal(firstCoord, p.Coordinate);
                    Assert.Equal(NodeState.UNKNOWN, p.State);
                });
                // Assert an objective is made for each square.
                Assert.DoesNotContain(firstCoord, seenCoordinates);
                seenCoordinates.Add(firstCoord);
            });
        }
Esempio n. 3
0
        public void TryDropAndReturnPossibility_Succeeds()
        {
            var puzzle        = new Puzzle(4);
            var matrix        = ExactCoverGraph.Create(puzzle);
            var possibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
                new FakePossibility(),
            };
            var        toDrop            = possibilities[0];
            var        concreteObjective = Objective.CreateFullyConnected(matrix, possibilities, 2);
            IObjective objective         = concreteObjective;

            Assert.True(objective.TryDropPossibility(toDrop.AttachedObjectives.First()));
            Assert.Equal(2, concreteObjective.CountUnknown);
            Assert.Equal(2, objective.GetUnknownDirectPossibilities().Count());
            Assert.Contains(possibilities[1], objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[2], objective.GetUnknownDirectPossibilities());
            Assert.Empty(toDrop.DroppedFromObjectives);

            objective.ReturnPossibility(toDrop.AttachedObjectives.First());
            Assert.Equal(3, concreteObjective.CountUnknown);
            Assert.Equal(3, objective.GetUnknownDirectPossibilities().Count());
            Assert.Contains(toDrop, objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[1], objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[2], objective.GetUnknownDirectPossibilities());
        }
Esempio n. 4
0
        public void TryDropPossibility_WhenRequired_Fails()
        {
            var puzzle        = new Puzzle(4);
            var matrix        = ExactCoverGraph.Create(puzzle);
            var possibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
                new FakePossibility(),
            };
            var        toDrop            = possibilities[0];
            var        concreteObjective = Objective.CreateFullyConnected(matrix, possibilities, 3);
            IObjective objective         = concreteObjective;

            Assert.False(objective.TryDropPossibility(toDrop.AttachedObjectives.First()));
            Assert.Equal(3, concreteObjective.CountUnknown);
            Assert.Equal(3, objective.GetUnknownDirectPossibilities().Count());
            Assert.Contains(toDrop, objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[1], objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[2], objective.GetUnknownDirectPossibilities());
        }
Esempio n. 5
0
        public void CreateWithPossibilities_ConnectsCorrectly(int numPossibilities, int numToSatisfy)
        {
            var        possibilities     = Possibilities.CreatePossibilities(new Coordinate(), numPossibilities);
            var        concreteObjective = OptionalObjective.CreateWithPossibilities(possibilities, numToSatisfy);
            IObjective objective         = concreteObjective;

            Assert.Equal(numToSatisfy, concreteObjective.TotalCountToSatisfy);
            Assert.Equal(NodeState.UNKNOWN, concreteObjective.State);
            Assert.False(objective.IsRequired);
            Assert.Equal(
                new HashSet <IPossibility>(possibilities),
                new HashSet <IPossibility>(objective.GetUnknownDirectPossibilities()));
        }
        public void Constrain_ReturnsExpectedConstraints()
        {
            int size = 4;

            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 ColumnUniquenessConstraint().TryConstrain(puzzle, matrix));

            Assert.Equal(
                size * possibleValues.Length + squareObjectives.Count,
                matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Count());
            Dictionary <int, HashSet <int> > columnsToValues = new();

            for (int i = 0; i < size; ++i)
            {
                columnsToValues[i] = new HashSet <int>();
            }
            var expectedRows = new int[] { 0, 1, 2, 3 };

            Assert.All(matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities(),
                       concreteObjective =>
            {
                if (squareObjectives.Contains(concreteObjective))
                {
                    return;
                }
                IObjective objective = concreteObjective;
                var possibilities    = objective.GetUnknownDirectPossibilities().Cast <Possibility>().ToArray();
                int column           = possibilities[0].Coordinate.Column;
                int value            = possibilities[0].Index;
                Assert.DoesNotContain(value, columnsToValues[column]);
                columnsToValues[column].Add(value);
                var expectedCoordinates = expectedRows.Select(row => new Coordinate(row, column)).ToArray();
                Assert.Equal(expectedCoordinates.Length, possibilities.Length);
                Assert.All(possibilities, p =>
                {
                    Assert.Contains(p.Coordinate, expectedCoordinates);
                    Assert.Equal(value, p.Index);
                });
                Assert.All(expectedCoordinates, c => Assert.NotNull(possibilities.SingleOrDefault(p => p.Coordinate == c)));
            });
            Assert.All(
                columnsToValues.Values,
                values => Assert.Equal(new HashSet <int> {
                0, 1, 2, 3
            }, values));
        }
Esempio n. 7
0
        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));
        }
Esempio n. 8
0
        public void TrySelectPossibility_WithUndetachablePossibility_Fails()
        {
            var puzzle        = new Puzzle(4);
            var matrix        = ExactCoverGraph.Create(puzzle);
            var possibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
                new FakePossibility(),
            };
            var toSelect     = possibilities[0];
            var undetachable = possibilities[2];

            undetachable.CanBeDetached = false;
            var        concreteObjective = Objective.CreateFullyConnected(matrix, possibilities, 1);
            IObjective objective         = concreteObjective;

            Assert.False(objective.TrySelectPossibility(toSelect.AttachedObjectives.First()));
            Assert.Empty(possibilities[1].DroppedFromObjectives);
            Assert.Empty(undetachable.DroppedFromObjectives);
            Assert.Contains(objective, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());
            Assert.Contains(toSelect, objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[1], objective.GetUnknownDirectPossibilities());
            Assert.Contains(undetachable, objective.GetUnknownDirectPossibilities());
        }
Esempio n. 9
0
        public void CreateFullyConnected_WithOptionalObjectives_ConnectsCorrectly()
        {
            var puzzle             = new Puzzle(4);
            var matrix             = ExactCoverGraph.Create(puzzle);
            var optionalObjectives = new OptionalObjective[] {
                OptionalObjective.CreateWithPossibilities(Possibilities.CreatePossibilities(new Coordinate(), 2), 1),
                OptionalObjective.CreateWithPossibilities(Possibilities.CreatePossibilities(new Coordinate(), 2), 1),
            };
            var        concreteObjective = Objective.CreateFullyConnected(matrix, optionalObjectives, 1);
            IObjective objective         = concreteObjective;

            Assert.Equal(
                new HashSet <IPossibility>(optionalObjectives),
                new HashSet <IPossibility>(objective.GetUnknownDirectPossibilities()));
        }