Valid Sudoku
Check that no digit repeats in any row, column or 3x3 box of a partly filled board. One set per row, column and box; every filled cell is added to its three sets.
Watch it animatedStep through it, with the running line highlighted. Free with an account.The idea
A board is valid when every row, every column and every 3x3 box holds each digit at most once. Give each of those 27 groups its own HashSet. Walk the filled cells once and Add the digit to the cell's row set, column set and box set. Add returns false when the digit is already there, which is exactly a repeat, so the board is invalid on the spot.
Code
public bool IsValidSudoku(char[][] board) {
var rows = new HashSet<char>[9];
var cols = new HashSet<char>[9];
var boxes = new HashSet<char>[9];
for (int i = 0; i < 9; i++) { rows[i] = new(); cols[i] = new(); boxes[i] = new(); }
for (int r = 0; r < 9; r++)
for (int c = 0; c < 9; c++) {
char d = board[r][c];
if (d == '.') continue; // empty cells cannot clash
int b = r / 3 * 3 + c / 3; // which 3x3 box, numbered 0 to 8
if (!rows[r].Add(d) || !cols[c].Add(d) || !boxes[b].Add(d))
return false; // d is already in this row, column or box
}
return true;
}Tips
- Box number = r / 3 * 3 + c / 3: r / 3 picks the band of three rows, c / 3 the stack of three columns.
- The same digit may appear many times on the board, as long as no two copies share a row, column or box. 6 appears three times in the default board before the clash.
- Only validity is checked, not solvability: a valid board may still have no solution.
In the .NET library
HashSet<char>.Add returns a bool, so test-and-insert is one call. The || short-circuits: once the row set says no, the column and box sets are never touched. With only 9 digits, a bool[9, 9] or a 9-bit mask per group is a faster drop-in replacement.