C#
ASP.NET
VSTO
Sudoku Solver (Easy)
A class that will solve 'Easy' or 'Mild' Sudoku puzzles.
public class SimpleSudokuSolver : Sodoku.ISudokuSolver { private Sudoku __sudoku; public SimpleSudokuSolver() { } #region ISudokuSolver Members public Sudoku Sudoku { get { return this.__sudoku; } set { this.__sudoku = value; } } public void Solve() { this.SolveA(); this.SolveB(); this.SolveA(); } #endregion protected void SolveA() { //loop through the grid testing for empty cells which can have only one //possible value according to the basic rules of the game, fill in these //cells and repeat the loop if at least one addition has been made bool foundone; do { foundone = false; for ( int i = 0; i < __sudoku.Length; i++ ) { for ( int j = 0; j < __sudoku.Length; j++ ) { if ( Sudoku.NULL_CHAR == __sudoku[ i, j ] ) { char[] possibles = __sudoku.GetCellValidCharacters( i, j ); if ( possibles.Length == 1 ) { __sudoku[ i, j ] = possibles[0]; foundone = true; } } } } } while ( foundone == true ); } //'cross-hatching' //the same idea can be applied to rows and columns protected void SolveB() { //for each block in the grid, find which characters are not present //and which cells are empty. then, for each character, try to rule //out all but one of the empty cells. repeat if at least one addition //to the grid has been made bool foundone; do { foundone = false; //for each block, eg. a 9x9 grid will have 9 blocks for ( int N = 0; N < __sudoku.Length; N++ ) { int block_length; int row_offset; int col_offset; ArrayList block_possibles; ArrayList empty_cells; block_length = __sudoku.BlockLength; row_offset = block_length * ( N / block_length ); col_offset = block_length * ( N % block_length ); block_possibles = new ArrayList( __sudoku.CharacterSet ); empty_cells = new ArrayList( block_length ); //first pass through the block removing any characters //that are present from the list of possible characters //also store empty cells for ( int i = 0; i < block_length; i++ ) { for ( int j = 0; j < block_length; j++ ) { int row = row_offset + i; int col = col_offset + j; char ch = __sudoku[ row, col ]; if ( Sudoku.NULL_CHAR != ch ) { block_possibles.Remove( ch ); } else { empty_cells.Add( new int[] { row, col } ); } } } //next, for each possible character, check each empty cell - if the //character is not valid in that cell because it already exists in //its row or column, then remove that cell from the list of possible //cells ( for that character ), if only one empty cell remains then //the character must belong in that cell foreach ( char possible_char in block_possibles ) { //initially, assume all empty cells are possible ArrayList possible_cells = new ArrayList( empty_cells ); foreach ( int[] cell in empty_cells ) { if ( !__sudoku.IsValidInRow( possible_char, cell[0] ) || !__sudoku.IsValidInColumn( possible_char, cell[1] ) ) { possible_cells.Remove( cell ); } } if ( possible_cells.Count == 1 ) { int[] cell = (int[]) possible_cells[0]; __sudoku[ cell[0], cell[1] ] = possible_char; empty_cells.Remove( cell ); foundone = true; } } } } while ( foundone == true ); } }