public void CopyWithNewReferences_WithoutIMissingBoxValuesTracker_Throws()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { null /* 1 */, null /* 4 */, 3, 2 },
                { null /* 2 */, null /* 3 */, null /* 1 */, 4 },
                { null /* 4 */, null /* 1 */, 2, 3 },
                { 3, null /* 2 */, 4, 1 }
            });
            var possibleValues = new PossibleValues(puzzle);
            var boxRule        = new BoxUniquenessRule(puzzle, possibleValues.AllPossible, false);
            var ruleKeeper     = new DynamicRuleKeeper(puzzle, possibleValues, new List <ISudokuRule> {
                boxRule
            });
            var heuristic = new UniqueInBoxHeuristic(
                puzzle, possibleValues, boxRule);

            var puzzleCopy                  = new Puzzle(puzzle);
            var possibleValuesCopy          = new PossibleValues(possibleValues);
            var ruleKeeperWithoutBoxTracker = new DynamicRuleKeeper(puzzleCopy, possibleValuesCopy,
                                                                    new List <ISudokuRule> {
                new ColumnUniquenessRule(puzzleCopy, possibleValues.AllPossible),
            });

            Assert.Throws <ArgumentException>(() => heuristic.CopyWithNewReferences(
                                                  puzzleCopy, possibleValuesCopy, ruleKeeperWithoutBoxTracker.GetRules()));
        }
Exemplo n.º 2
0
        public void Revert_RevertsSpecifiedBox()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, 3, null /* 1 */, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, 2, 3 },
                new int?[] { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule();

            Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues));
            IList <BitVector> initialPossibleValuesByBox = _GetPossibleValuesByBox(puzzle.Size, rule);
            var updatedCoordTracker = new CoordinateTracker(puzzle.Size);
            var coord = new Coordinate(1, 2);
            int val   = 1;

            rule.Update(in coord, val, updatedCoordTracker);

            var revertedCoordTracker = new CoordinateTracker(puzzle.Size);

            rule.Revert(coord, val, revertedCoordTracker);

            Assert.Equal(
                updatedCoordTracker.TrackedCoords.ToArray(),
                revertedCoordTracker.TrackedCoords.ToArray());
            for (int box = 0; box < initialPossibleValuesByBox.Count; box++)
            {
                Assert.Equal(
                    initialPossibleValuesByBox[box],
                    rule.GetMissingValuesForBox(box));
            }
        }
Exemplo n.º 3
0
        public void Update_SkippingRowsAndCols_AppendsOnlyOthersInBox()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, null /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, 3, null /* 1 */, null /* 4 */ },
                { null /* 4 */, null /* 1 */, 2, 3 },
                { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule         = new BoxUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size), true);
            var coordTracker = new CoordinateTracker(puzzle.Size);
            var coord        = new Coordinate(1, 3);
            int val          = 4;

            rule.Update(coord, val, coordTracker);
            Assert.Equal(
                new HashSet <Coordinate> {
                new Coordinate(0, 2)
            },
                new HashSet <Coordinate>(coordTracker.GetTrackedCoords().ToArray()));
            Assert.Equal(new BitVector(0b10100), rule.GetPossibleValues(new Coordinate(0, 0)));
            Assert.Equal(new BitVector(0b01010), rule.GetPossibleValues(new Coordinate(0, 2)));
            Assert.Equal(new BitVector(0b01010), rule.GetPossibleValues(new Coordinate(1, 2)));
            Assert.Equal(new BitVector(0b11110), rule.GetPossibleValues(new Coordinate(2, 0)));
            Assert.Equal(new BitVector(0b00000), rule.GetPossibleValues(new Coordinate(2, 2)));
        }
Exemplo n.º 4
0
        public void Revert_SkippingRowsAndCols_AppendsOnlyOthersInBox()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, 4, null /* 3 */, 2 },
                { null /* 2 */, null /* 3 */, null /* 1 */, null /* 4 */ },
                { null /* 4 */, null /* 1 */, 2, 3 },
                { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size), true);
            IList <BitVector> initialPossibleValuesByBox = _GetPossibleValuesByBox(puzzle.Size, rule);
            var coord = new Coordinate(1, 3);
            int val   = 4;

            rule.Update(in coord, val, new CoordinateTracker(puzzle.Size));

            var revertedCoordTracker = new CoordinateTracker(puzzle.Size);

            rule.Revert(coord, val, revertedCoordTracker);
            Assert.Equal(
                new HashSet <Coordinate> {
                new Coordinate(0, 2)
            },
                new HashSet <Coordinate>(revertedCoordTracker.GetTrackedCoords().ToArray()));
            for (int box = 0; box < initialPossibleValuesByBox.Count; box++)
            {
                Assert.Equal(
                    initialPossibleValuesByBox[box],
                    rule.GetMissingValuesForBox(box));
            }
        }
Exemplo n.º 5
0
        public void Update_UpdatesSpecifiedBox()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, 3, null /* 1 */, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, 2, 3 },
                new int?[] { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule();

            Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues));
            var coordTracker = new CoordinateTracker(puzzle.Size);
            var coord        = new Coordinate(1, 2);
            int val          = 1;

            rule.Update(coord, val, coordTracker);

            Assert.Equal(
                new HashSet <Coordinate> {
                new Coordinate(0, 2), new Coordinate(1, 3)
            },
                new HashSet <Coordinate>(coordTracker.TrackedCoords.ToArray()));
            Assert.Equal(new BitVector(0b10100), rule.GetPossibleValues(new Coordinate(0, 0)));
            Assert.Equal(new BitVector(0b11000), rule.GetPossibleValues(new Coordinate(0, 2)));
            Assert.Equal(new BitVector(0b11110), rule.GetPossibleValues(new Coordinate(2, 0)));
            Assert.Equal(new BitVector(0b00000), rule.GetPossibleValues(new Coordinate(2, 2)));
        }
Exemplo n.º 6
0
        public void TrySolve_MegaPuzzle_Solves()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { null, null, null, null, 10, 1, null, 8, null, 15, 3, 11, null, 2, 16, null },
                new int?[] { 14, null, 2, null, null, 4, 3, null, null, 13, 8, null, null, 12, null, null },
                new int?[] { null, null, null, 12, null, null, null, 15, null, null, null, 7, null, null, 9, 10 },
                new int?[] { 1, 10, 15, null, 6, null, null, null, null, 14, null, null, null, null, null, 11 },
                new int?[] { null, 11, 14, 6, null, null, null, 9, 13, 8, null, null, null, null, 2, 3 },
                new int?[] { 12, null, null, null, 4, null, 7, 3, 11, 6, null, null, 16, null, 5, null },
                new int?[] { 13, 16, null, 2, null, null, null, 1, null, null, 5, null, 10, 9, null, null },
                new int?[] { null, 4, null, null, 13, null, 2, null, null, null, 16, 3, 11, null, null, null },
                new int?[] { null, null, null, 10, 3, 6, null, null, null, 9, null, 12, null, null, 4, null },
                new int?[] { null, null, 12, 15, null, 9, null, null, 7, null, null, null, 1, null, 3, 14 },
                new int?[] { null, 1, null, 4, null, null, 5, 12, 3, 10, null, 8, null, null, null, 2 },
                new int?[] { 3, 6, null, null, null, null, 15, 10, 4, null, null, null, 12, 5, 7, null },
                new int?[] { 2, null, null, null, null, null, 4, null, null, null, null, 15, null, 16, 11, 9 },
                new int?[] { 4, 14, null, null, 16, null, null, null, 2, null, null, null, 6, null, null, null },
                new int?[] { null, null, 16, null, null, 7, 8, null, null, 4, 10, null, null, 14, null, 5 },
                new int?[] { null, 3, 6, null, 9, 12, 14, null, 8, null, 13, 16, null, null, null, null }
            });
            var rowRule      = new RowUniquenessRule();
            var columnRule   = new ColumnUniquenessRule();
            var boxRule      = new BoxUniquenessRule();
            var diagonalRule = new DiagonalUniquenessRule();
            var ruleKeeper   = new DynamicRuleKeeper(
                new IRule[] { rowRule, columnRule, boxRule, diagonalRule });
            var heuristic = new StandardHeuristic(
                rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver <PuzzleWithPossibleValues>(ruleKeeper, heuristic);

            Assert.True(solver.TrySolve(puzzle));
            _AssertMegaPuzzleSolved(puzzle);
        }
Exemplo n.º 7
0
        public void Constructor_AcceptsValidPuzzleSizes(int size)
        {
            int?[,] matrix = new int?[size, size];
            var puzzle = new Puzzle(matrix);
            var rule   = new BoxUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size), false);

            Assert.NotNull(rule);
        }
Exemplo n.º 8
0
        private IList <BitVector> _GetPossibleValuesByBox(int numBoxes, BoxUniquenessRule rule)
        {
            var possibleBoxValues = new List <BitVector>();

            for (int box = 0; box < numBoxes; box++)
            {
                possibleBoxValues.Add(rule.GetMissingValuesForBox(box));
            }
            return(possibleBoxValues);
        }
Exemplo n.º 9
0
        public void TryInit_WithDuplicateValueInBox_Fails()
        {
            var puzzle = new PuzzleWithPossibleValues(
                new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, /* INCORRECT */ 1, null /* 1 */, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, 2, 3 },
                new int?[] { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule();

            Assert.False(rule.TryInit(puzzle, puzzle.UniquePossibleValues));
        }
Exemplo n.º 10
0
        public void Constructor_FiltersCorrectly()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, null /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, 3, null /* 1 */, null /* 4 */ },
                { null /* 4 */, null /* 1 */, 2, 3 },
                { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size), false);

            Assert.Equal(new BitVector(0b10100), rule.GetPossibleValues(new Coordinate(0, 0)));
            Assert.Equal(new BitVector(0b11010), rule.GetPossibleValues(new Coordinate(0, 2)));
            Assert.Equal(new BitVector(0b11110), rule.GetPossibleValues(new Coordinate(2, 0)));
            Assert.Equal(new BitVector(0b00000), rule.GetPossibleValues(new Coordinate(2, 2)));
        }
Exemplo n.º 11
0
        public bool SudokuSpiceDynamicMultiple(PuzzleSample puzzle)
        {
            var p          = new PuzzleWithPossibleValues(puzzle.NullableJaggedMatrix);
            var rowRule    = new RowUniquenessRule();
            var columnRule = new ColumnUniquenessRule();
            var boxRule    = new BoxUniquenessRule();
            var ruleKeeper = new DynamicRuleKeeper(
                new IRule[] { rowRule, columnRule, boxRule });
            var heuristic = new StandardHeuristic(
                rowRule, columnRule, boxRule);
            var solver = new RuleBased.PuzzleSolver <PuzzleWithPossibleValues>(ruleKeeper, heuristic);
            var result = solver.Solve(p, randomizeGuesses: true);

            return(result.NumEmptySquares == 0);
        }
Exemplo n.º 12
0
        public void TryInit_ValidPuzzle_FiltersCorrectly()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, 3, null /* 1 */, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, 2, 3 },
                new int?[] { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule();

            Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues));

            Assert.Equal(new BitVector(0b10100), rule.GetPossibleValues(new Coordinate(0, 0)));
            Assert.Equal(new BitVector(0b11010), rule.GetPossibleValues(new Coordinate(0, 2)));
            Assert.Equal(new BitVector(0b11110), rule.GetPossibleValues(new Coordinate(2, 0)));
            Assert.Equal(new BitVector(0b00000), rule.GetPossibleValues(new Coordinate(2, 2)));
        }
Exemplo n.º 13
0
        public void Constructor_WithDuplicateValueInBox_Throws()
        {
            ArgumentException ex = Assert.Throws <ArgumentException>(() =>
            {
                var rule = new BoxUniquenessRule(
                    new Puzzle(
                        new int?[, ] {
                    { 1, null /* 4 */, null /* 3 */, 2 },
                    { null /* 2 */, /* INCORRECT */ 1, null /* 1 */, null /* 4 */ },
                    { null /* 4 */, null /* 1 */, 2, 3 },
                    { null /* 3 */, null /* 2 */, 4, 1 }
                }),
                    BitVector.CreateWithSize(4),
                    false);
            });

            Assert.Contains("Puzzle has duplicate value in box", ex.Message);
        }
Exemplo n.º 14
0
        public void Solve_ValidPuzzle_SolvesPuzzle(Puzzle puzzle)
        {
            var possibleValues = new PossibleValues(puzzle);
            var rowRule        = new RowUniquenessRule(puzzle, possibleValues.AllPossible);
            var columnRule     = new ColumnUniquenessRule(puzzle, possibleValues.AllPossible);
            var boxRule        = new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true);
            var ruleKeeper     = new DynamicRuleKeeper(
                puzzle, possibleValues,
                new List <ISudokuRule> {
                rowRule, columnRule, boxRule
            });
            var heuristic = new StandardHeuristic(
                puzzle, possibleValues, rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver(puzzle, possibleValues, ruleKeeper, heuristic);

            solver.Solve();
            _AssertPuzzleSolved(puzzle);
        }
Exemplo n.º 15
0
        public bool SudokuSpiceDynamicMultiple(PuzzleSample puzzle)
        {
            var p = new Puzzle(puzzle.NullableMatrix);
            var possibleValues = new PossibleValues(p);
            var rowRule        = new RowUniquenessRule(p, possibleValues.AllPossible);
            var columnRule     = new ColumnUniquenessRule(p, possibleValues.AllPossible);
            var boxRule        = new BoxUniquenessRule(p, possibleValues.AllPossible, true);
            var ruleKeeper     = new DynamicRuleKeeper(
                p, possibleValues,
                new List <ISudokuRule> {
                rowRule, columnRule, boxRule
            });
            var heuristic = new StandardHeuristic(
                p, possibleValues, rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver(p, possibleValues, ruleKeeper, heuristic);

            solver.SolveRandomly();
            return(p.NumEmptySquares == 0);
        }
Exemplo n.º 16
0
        public void CopyWithNewReference_CreatesDeepCopy()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, 3, null /* 1 */, null /* 4 */ },
                new int?[] { null /* 4 */, null /* 1 */, 2, 3 },
                new int?[] { null /* 3 */, null /* 2 */, 4, 1 }
            });
            var rule = new BoxUniquenessRule();

            Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues));

            var   puzzleCopy = new PuzzleWithPossibleValues(puzzle);
            IRule ruleCopy   = rule.CopyWithNewReference(puzzleCopy);
            int   val        = 3;
            var   coord      = new Coordinate(3, 0);

            ruleCopy.Update(coord, val, new CoordinateTracker(puzzle.Size));
            Assert.NotEqual(rule.GetPossibleValues(coord), ruleCopy.GetPossibleValues(coord));

            puzzleCopy[coord] = val;
            var secondCoord  = new Coordinate(3, 1);
            int secondVal    = 2;
            var coordTracker = new CoordinateTracker(puzzle.Size);

            ruleCopy.Update(secondCoord, secondVal, coordTracker);
            var originalCoordTracker = new CoordinateTracker(puzzle.Size);

            rule.Update(secondCoord, secondVal, originalCoordTracker);
            Assert.Equal(
                new HashSet <Coordinate> {
                new Coordinate(2, 0), new Coordinate(2, 1)
            },
                new HashSet <Coordinate>(coordTracker.TrackedCoords.ToArray()));
            Assert.Equal(
                new HashSet <Coordinate> {
                new Coordinate(2, 0), new Coordinate(2, 1), new Coordinate(3, 0)
            },
                new HashSet <Coordinate>(originalCoordTracker.TrackedCoords.ToArray()));
        }
Exemplo n.º 17
0
        public void GetPossibleValues_MatchesGetPossibleBoxValues()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { 1, null /* 4 */, null /* 3 */, 2 },
                { null /* 2 */, null /* 3 */, null /* 1 */, 4 },
                { null /* 4 */, 1, null /* 2 */, 3 },
                { 3, null /* 2 */, null /* 4 */, 1 }
            });
            var rule = new BoxUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size), false);
            IList <BitVector> possibleValuesByBox = _GetPossibleValuesByBox(puzzle.Size, rule);

            for (int row = 0; row < puzzle.Size; row++)
            {
                for (int column = 0; column < puzzle.Size; column++)
                {
                    int box = puzzle.GetBoxIndex(row, column);
                    Assert.Equal(
                        possibleValuesByBox[box],
                        rule.GetPossibleValues(new Coordinate(row, column)));
                }
            }
        }
Exemplo n.º 18
0
        public void Solve_MegaPuzzle_Solves()
        {
            var puzzle = new Puzzle(new int?[, ] {
                { null, null, null, null, 10, 1, null, 8, null, 15, 3, 11, null, 2, 16, null },
                { 14, null, 2, null, null, 4, 3, null, null, 13, 8, null, null, 12, null, null },
                { null, null, null, 12, null, null, null, 15, null, null, null, 7, null, null, 9, 10 },
                { 1, 10, 15, null, 6, null, null, null, null, 14, null, null, null, null, null, 11 },
                { null, 11, 14, 6, null, null, null, 9, 13, 8, null, null, null, null, 2, 3 },
                { 12, null, null, null, 4, null, 7, 3, 11, 6, null, null, 16, null, 5, null },
                { 13, 16, null, 2, null, null, null, 1, null, null, 5, null, 10, 9, null, null },
                { null, 4, null, null, 13, null, 2, null, null, null, 16, 3, 11, null, null, null },
                { null, null, null, 10, 3, 6, null, null, null, 9, null, 12, null, null, 4, null },
                { null, null, 12, 15, null, 9, null, null, 7, null, null, null, 1, null, 3, 14 },
                { null, 1, null, 4, null, null, 5, 12, 3, 10, null, 8, null, null, null, 2 },
                { 3, 6, null, null, null, null, 15, 10, 4, null, null, null, 12, 5, 7, null },
                { 2, null, null, null, null, null, 4, null, null, null, null, 15, null, 16, 11, 9 },
                { 4, 14, null, null, 16, null, null, null, 2, null, null, null, 6, null, null, null },
                { null, null, 16, null, null, 7, 8, null, null, 4, 10, null, null, 14, null, 5 },
                { null, 3, 6, null, 9, 12, 14, null, 8, null, 13, 16, null, null, null, null }
            });
            var possibleValues = new PossibleValues(puzzle);
            var rowRule        = new RowUniquenessRule(puzzle, possibleValues.AllPossible);
            var columnRule     = new ColumnUniquenessRule(puzzle, possibleValues.AllPossible);
            var boxRule        = new BoxUniquenessRule(puzzle, possibleValues.AllPossible, true);
            var diagonalRule   = new DiagonalUniquenessRule(puzzle, possibleValues.AllPossible);
            var ruleKeeper     = new DynamicRuleKeeper(
                puzzle, possibleValues,
                new List <ISudokuRule> {
                rowRule, columnRule, boxRule, diagonalRule
            });
            var heuristic = new StandardHeuristic(
                puzzle, possibleValues, rowRule, columnRule, boxRule);
            var solver = new PuzzleSolver(puzzle, possibleValues, ruleKeeper, heuristic);

            solver.Solve();
            _AssertMegaPuzzleSolved(puzzle);
        }
Exemplo n.º 19
0
        public void GetPossibleValues_MatchesGetPossibleBoxValues()
        {
            var puzzle = new PuzzleWithPossibleValues(new int?[][] {
                new int?[] { 1, null /* 4 */, null /* 3 */, 2 },
                new int?[] { null /* 2 */, null /* 3 */, null /* 1 */, 4 },
                new int?[] { null /* 4 */, 1, null /* 2 */, 3 },
                new int?[] { 3, null /* 2 */, null /* 4 */, 1 }
            });
            var rule = new BoxUniquenessRule();

            Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues));
            IList <BitVector> possibleValuesByBox = _GetPossibleValuesByBox(puzzle.Size, rule);

            for (int row = 0; row < puzzle.Size; row++)
            {
                for (int column = 0; column < puzzle.Size; column++)
                {
                    int box = Boxes.CalculateBoxIndex(new(row, column), Boxes.IntSquareRoot(puzzle.Size));
                    Assert.Equal(
                        possibleValuesByBox[box],
                        rule.GetPossibleValues(new Coordinate(row, column)));
                }
            }
        }