public void Revert_RevertsSpecifiedDiagonal() { var puzzle = new Puzzle(new int?[, ] { { 1, null, null, 4 }, { null, null, 3, 2 }, { 2, null, null, null }, { null, null, null, null } }); var rule = new DiagonalUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size)); BitVector[,] initialPossibles = _GetPossibleValues(puzzle.Size, rule); var updatedCoordTracker = new CoordinateTracker(puzzle.Size); var coord = new Coordinate(2, 2); int val = 4; rule.Update(in coord, val, updatedCoordTracker); var revertedCoordTracker = new CoordinateTracker(puzzle.Size); rule.Revert(coord, val, revertedCoordTracker); Assert.Equal( revertedCoordTracker.GetTrackedCoords().ToArray(), updatedCoordTracker.GetTrackedCoords().ToArray()); for (int row = 0; row < puzzle.Size; row++) { for (int col = 0; col < puzzle.Size; col++) { Assert.Equal( initialPossibles[row, col], rule.GetPossibleValues(new Coordinate(row, col))); } } }
public void Constructor_FiltersCorrectly() { var puzzle = new Puzzle(new int?[, ] { { 1, null, null, 4 }, { null, null, 3, 2 }, { 2, null, null, null }, { null, null, null, null } }); var rule = new DiagonalUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size)); var expectedBackwardPossibles = new BitVector(0b11100); var expectedForwardPossibles = new BitVector(0b00110); var expectedOtherPossibles = new BitVector(0b11110); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(0, 0))); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(1, 1))); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(2, 2))); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(3, 3))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(0, 3))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(1, 2))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(2, 1))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(3, 0))); Assert.Equal(expectedOtherPossibles, rule.GetPossibleValues(new Coordinate(0, 2))); Assert.Equal(expectedOtherPossibles, rule.GetPossibleValues(new Coordinate(1, 3))); }
public void Revert_OnNonDiagonal_DoesNothing() { var puzzle = new Puzzle(new int?[, ] { { 1, null, null, 4 }, { null, null, 3, 2 }, { 2, null, null, null }, { null, null, null, null } }); var rule = new DiagonalUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size)); BitVector[,] previousPossibles = _GetPossibleValues(puzzle.Size, rule); var coordTracker = new CoordinateTracker(puzzle.Size); var coord = new Coordinate(0, 1); int val = 2; rule.Update(in coord, val, new CoordinateTracker(puzzle.Size)); rule.Revert(coord, val, coordTracker); Assert.Equal(0, coordTracker.NumTracked); for (int row = 0; row < puzzle.Size; row++) { for (int col = 0; col < puzzle.Size; col++) { Assert.Equal( previousPossibles[row, col], rule.GetPossibleValues(new Coordinate(row, col))); } } }
public void Revert_WithoutAffectedCoordsList_RevertsSpecifiedDiagonal() { var puzzle = new PuzzleWithPossibleValues(new int?[][] { new int?[] { 1, null, null, 4 }, new int?[] { null, null, 3, 2 }, new int?[] { 2, null, null, null }, new int?[] { null, null, null, null } }); var rule = new DiagonalUniquenessRule(); Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues)); BitVector[,] initialPossibles = _GetPossibleValues(puzzle.Size, rule); var coord = new Coordinate(2, 1); int val = 1; rule.Update(in coord, val, new CoordinateTracker(puzzle.Size)); rule.Revert(coord, val); for (int row = 0; row < puzzle.Size; row++) { for (int col = 0; col < puzzle.Size; col++) { Assert.Equal( initialPossibles[row, col], rule.GetPossibleValues(new Coordinate(row, col))); } } }
public void Update_OnDiagonal_UpdatesSpecifiedDiagonal() { var puzzle = new PuzzleWithPossibleValues(new int?[][] { new int?[] { 1, null, null, 4 }, new int?[] { null, null, 3, 2 }, new int?[] { 2, null, null, null }, new int?[] { null, null, null, null } }); var rule = new DiagonalUniquenessRule(); Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues)); var coordTracker = new CoordinateTracker(puzzle.Size); var coord = new Coordinate(2, 2); int val = 4; rule.Update(coord, val, coordTracker); Assert.Equal( new HashSet <Coordinate> { new Coordinate(1, 1), new Coordinate(3, 3) }, new HashSet <Coordinate>(coordTracker.TrackedCoords.ToArray())); Assert.Equal(new BitVector(0b01100), rule.GetPossibleValues(new Coordinate(1, 1))); Assert.Equal(new BitVector(0b00110), rule.GetPossibleValues(new Coordinate(1, 2))); Assert.Equal(new BitVector(0b11110), rule.GetPossibleValues(new Coordinate(0, 2))); }
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); }
public void Constructor_AcceptsValidPuzzleSizes(int size) { int?[,] matrix = new int?[size, size]; var puzzle = new Puzzle(matrix); var rule = new DiagonalUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size)); Assert.NotNull(rule); }
public void TryInit_WithDuplicateValueInDiagonal_Fails() { var puzzle = new PuzzleWithPossibleValues(new int?[][] { new int?[] { 1, null, null, 4 }, new int?[] { null, 1, 3, 2 }, new int?[] { 2, null, null, null }, new int?[] { null, null, null, null } }); var rule = new DiagonalUniquenessRule(); Assert.False(rule.TryInit(puzzle, puzzle.UniquePossibleValues)); }
private BitVector[,] _GetPossibleValues(int puzzleSize, DiagonalUniquenessRule rule) { var possibleValues = new BitVector[puzzleSize, puzzleSize]; for (int row = 0; row < puzzleSize; row++) { for (int col = 0; col < puzzleSize; col++) { possibleValues[row, col] = rule.GetPossibleValues(new Coordinate(row, col)); } } return(possibleValues); }
public void Constructor_WithDuplicateValueInDiagonal_Throws() { ArgumentException ex = Assert.Throws <ArgumentException>(() => { var puzzle = new Puzzle(new int?[, ] { { 1, null, null, 4 }, { null, 1, 3, 2 }, { 2, null, null, null }, { null, null, null, null } }); var rule = new DiagonalUniquenessRule(puzzle, _GetAllPossibleValues(puzzle.Size)); }); Assert.Contains("Puzzle does not satisfy diagonal uniqueness rule", ex.Message); }
public void CopyWithNewReference_CreatesDeepCopy() { var puzzle = new PuzzleWithPossibleValues(new int?[][] { new int?[] { 1, null, null, 4 }, new int?[] { null, null, 3, 2 }, new int?[] { 4, null, null, null }, new int?[] { null, null, null, null } }); var rule = new DiagonalUniquenessRule(); Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues)); var puzzleCopy = new PuzzleWithPossibleValues(puzzle); IRule ruleCopy = rule.CopyWithNewReference(puzzleCopy); int val = 4; var coord = new Coordinate(1, 1); ruleCopy.Update(coord, val, new CoordinateTracker(puzzle.Size)); Assert.NotEqual(rule.GetPossibleValues(coord), ruleCopy.GetPossibleValues(coord)); puzzleCopy[coord] = val; var secondCoord = new Coordinate(2, 2); 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(3, 3) }, new HashSet <Coordinate>(coordTracker.TrackedCoords.ToArray())); Assert.Equal( new HashSet <Coordinate> { new Coordinate(1, 1), new Coordinate(3, 3) }, new HashSet <Coordinate>(originalCoordTracker.TrackedCoords.ToArray())); }
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); }
public void TryInit_ValidPuzzle_FiltersCorrectly() { var puzzle = new PuzzleWithPossibleValues(new int?[][] { new int?[] { 1, null, null, 4 }, new int?[] { null, null, 3, 2 }, new int?[] { 2, null, null, null }, new int?[] { null, null, null, null } }); var rule = new DiagonalUniquenessRule(); Assert.True(rule.TryInit(puzzle, puzzle.UniquePossibleValues)); var expectedBackwardPossibles = new BitVector(0b11100); var expectedForwardPossibles = new BitVector(0b00110); var expectedOtherPossibles = new BitVector(0b11110); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(0, 0))); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(1, 1))); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(2, 2))); Assert.Equal(expectedBackwardPossibles, rule.GetPossibleValues(new Coordinate(3, 3))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(0, 3))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(1, 2))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(2, 1))); Assert.Equal(expectedForwardPossibles, rule.GetPossibleValues(new Coordinate(3, 0))); Assert.Equal(expectedOtherPossibles, rule.GetPossibleValues(new Coordinate(0, 2))); Assert.Equal(expectedOtherPossibles, rule.GetPossibleValues(new Coordinate(1, 3))); }