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)); }
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); }