Пример #1
0
        private IEnumerable <SingleStepSolution.Candidate> GetEliminations(
            IEnumerable <Tuple <Cell, int> > cellCandidatePairs, bool perRow, SudokuPuzzle sudokuPuzzle)
        {
            var eliminations = new List <SingleStepSolution.Candidate>();

            foreach (var cellCandidatePair in cellCandidatePairs)
            {
                var cell       = cellCandidatePair.Item1;
                var candidate  = cellCandidatePair.Item2;
                var blockIndex = sudokuPuzzle.GetBlockIndex(cell);
                var block      = sudokuPuzzle.Blocks[blockIndex.RowIndex, blockIndex.ColumnIndex];

                foreach (var blockCell in block.Cells)
                {
                    // Ignore the same cell, or block cells that do not contain candidate
                    if (blockCell == cell || !blockCell.CanBe.Contains(candidate))
                    {
                        continue;
                    }

                    // If outside cells are part of the same row,
                    // ignore block cells that are part of that same row (similar for columns)
                    if ((perRow && cell.RowIndex == blockCell.RowIndex) ||
                        (!perRow && cell.ColumnIndex == blockCell.ColumnIndex))
                    {
                        continue;
                    }

                    eliminations.Add(new SingleStepSolution.Candidate(
                                         blockCell.RowIndex, blockCell.ColumnIndex, candidate));
                }
            }

            return(eliminations);
        }
        public void GetBlockIndexForNullTest()
        {
            var sudokuPuzzle = new SudokuPuzzle(_sudoku);
            var cellIndex    = sudokuPuzzle.GetBlockIndex(null);

            Assert.That(cellIndex.RowIndex, Is.EqualTo(-1));
            Assert.That(cellIndex.ColumnIndex, Is.EqualTo(-1));
        }
        public void GetBlockIndexForNonExistingCellTest()
        {
            var sudokuPuzzle = new SudokuPuzzle(_sudoku);
            var cellIndex    = sudokuPuzzle.GetBlockIndex(new Cell(0, 0, 0));

            // Cell equality is compared by reference (Object.ReferenceEquals)
            Assert.That(cellIndex.RowIndex, Is.EqualTo(-1));
            Assert.That(cellIndex.ColumnIndex, Is.EqualTo(-1));
        }
        public void GetBlockIndexTest()
        {
            var sudokuPuzzle = new SudokuPuzzle(_sudoku);
            var cell         = sudokuPuzzle.Cells[4, 7];

            Assert.That(cell.Value, Is.EqualTo(5));

            var cellIndex = sudokuPuzzle.GetBlockIndex(cell);

            Assert.That(cellIndex.RowIndex, Is.EqualTo(1));
            Assert.That(cellIndex.ColumnIndex, Is.EqualTo(2));
        }
Пример #5
0
        private bool SolvePuzzle(SudokuPuzzle sudokuPuzzle)
        {
            if (sudokuPuzzle.IsSolved())
            {
                return(true);
            }

            var unsolvedCells = sudokuPuzzle.Cells.OfType <Cell>().Where(x => !x.HasValue).OrderBy(x => x.CanBe.Count).ToArray();

            // for each cell
            foreach (var cell in unsolvedCells)
            {
                var row        = sudokuPuzzle.Rows[cell.RowIndex];
                var column     = sudokuPuzzle.Columns[cell.ColumnIndex];
                var blockIndex = sudokuPuzzle.GetBlockIndex(cell);
                var block      = sudokuPuzzle.Blocks[blockIndex.RowIndex, blockIndex.ColumnIndex];

                var potentialCellValues = new List <int>(cell.CanBe);

                // for each potential value
                foreach (var value in potentialCellValues)
                {
                    var usedInRow    = row.Cells.Count(x => x.Value == value) > 0;
                    var usedInColumn = column.Cells.Count(x => x.Value == value) > 0;
                    var usedInBlock  = block.Cells.OfType <Cell>().Count(x => x.Value == value) > 0;

                    // if potential value already used in row, column or block, skip it
                    if (usedInRow || usedInColumn || usedInBlock)
                    {
                        continue;
                    }

                    // try to recursively solve the puzzle
                    cell.Value = value;
                    if (SolvePuzzle(sudokuPuzzle))
                    {
                        return(true);
                    }
                    // if puzzle cannot be solve, revert the value
                    else
                    {
                        cell.Value = 0;
                        cell.CanBe.AddRange(potentialCellValues);
                    }
                }
                return(false);
            }
            return(false);
        }