Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
class Solution {
public:
typedef vector<vector<char> > VVC;
char getIthCh(const VVC& board, int x, int y, int idx, int type) {
if (type == 1)
return board[x][idx];
else if (type == 2)
return board[idx][y];
else if (type == 3) {
int bx = x / 3 * 3, by = y / 3 * 3, vx = idx / 3, vy = idx % 3;
return board[bx+vx][by+vy];
}
return NULL;
}
bool valid(const VVC& board, int x, int y) {
int exist[9] = {0};
for (int t = 1; t <= 3; ++t) {
memset(exist, 0, sizeof(int)*9);
for (int i = 0; i < 9; ++i) {
char ch = getIthCh(board, x, y, i, t);
if (ch != '.') {
if (exist[ch-'1'])
return false;
else
exist[ch-'1'] = 1;
}
}
}
return true;
}
bool solve(vector<vector<char>>& board) {
int i, j;
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j)
if (board[i][j] == '.') {
for (char ch = '1'; ch <= '9'; ++ch) {
board[i][j] = ch;
if (valid(board, i, j) && solve(board) )
return true;
board[i][j] = '.';
}
return false;
}
return true;
}
void solveSudoku(vector<vector<char> > &board) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
solve(board);
}
};
A wrong code, find the bug:
class Solution {
public:
typedef vector<vector<char> > VVC;
char getIthCh(const VVC& board, int x, int y, int idx, int type) {
if (type == 1)
return board[x][idx];
else if (type == 2)
return board[idx][y];
else if (type == 3) {
int bx = x / 3 * 3, by = y / 3 * 3, vx = idx / 3, vy = idx % 3;
return board[bx+vx][by+vy];
}
return NULL;
}
bool valid(const VVC& board, int x, int y) {
int exist[10] = {0};
for (int t = 1; t <= 3; ++t) {
for (int i = 0; i < 10; ++i) {
char ch = getIthCh(board, x, y, i, t);
if (exist[ch-'0'])
return false;
}
}
return true;
}
bool solve(vector<vector<char>>& board) {
int i, j;
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j)
if (board[i][j] == '.') {
for (char ch = '1'; ch <= '9'; ++ch) {
board[i][j] = ch;
if (valid(board, i, j) && solve(board) )
return true;
board[i][j] = '.';
}
return false;
}
return true;
}
void solveSudoku(vector<vector<char> > &board) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
solve(board);
}
};
It's not convenient to record the options for every node when backtrack, so a direct traverse is inevitable. The code is like:
class Solution {
public:
bool valid(vector<vector<char>>& board, int x, int y) {
int i, j;
int exist[9] = {0};
for (i = 0; i < 9; ++i)
if (board[x][i] != '.')
if (exist[board[x][i] - '1'] == 0)
exist[board[x][i] - '1'] = 1;
else
return false;
memset(exist,0,sizeof(int) * 9);
for (i = 0; i < 9; ++i)
if (board[i][y] != '.')
if (exist[board[i][y] - '1'] == 0)
exist[board[i][y] - '1'] = 1;
else
return false;
int x_offset = x / 3, y_offset = y / 3;
memset(exist,0,sizeof(int) * 9);
for (i = 0; i < 9; ++i) {
char ch = board[i / 3 + x_offset * 3][i % 3 + y_offset * 3];
if (ch != '.')
if (exist[ch - '1'] == 0)
exist[ch - '1'] = 1;
else
return false;
}
return true;
}
bool solve(vector<vector<char>>& board) {
int i, j;
for (i = 0; i < 9; ++i)
for (j = 0; j < 9; ++j)
if (board[i][j] == '.') {
for (char ch = '1'; ch <= '9'; ++ch) {
board[i][j] = ch;
if (valid(board, i, j) && solve(board) )
return true;
board[i][j] = '.';
}
return false;
}
return true;
}
void solveSudoku(vector<vector<char> > &board) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
solve(board);
}
};
Read input from file, then write to file:
x 3 x x 2 x 4 x x
9 x x x 4 x 8 x x
8 x x x 3 7 x x 5
3 5 x x x 9 7 x 8
x x 8 4 x 3 1 x x
7 x 9 2 x x x 4 3
4 x x 8 1 x x x 7
x x 5 x 9 x x x 2
x x 7 x 5 x x 1 x
x x 7 3 5 x x 8 x
x x x x 6 8 x 3 4
x x x x x x 1 9 x
6 x x x x x 8 5 7
x x x 5 x 6 x x x
5 8 9 x x x x x 6
x 5 8 x x x x x x
9 6 x 7 3 x x x x
x 1 x x 4 2 5 x x
5 3 6 9 2 8 4 7 1
9 7 2 5 4 1 8 3 6
8 4 1 6 3 7 2 9 5
3 5 4 1 6 9 7 2 8
6 2 8 4 7 3 1 5 9
7 1 9 2 8 5 6 4 3
4 9 3 8 1 2 5 6 7
1 6 5 7 9 4 3 8 2
2 8 7 3 5 6 9 1 4
4 9 7 3 5 1 6 8 2
1 2 5 9 6 8 7 3 4
8 3 6 4 2 7 1 9 5
6 4 1 2 9 3 8 5 7
3 7 2 5 8 6 9 4 1
5 8 9 1 7 4 3 2 6
2 5 8 6 1 9 4 7 3
9 6 4 7 3 5 2 1 8
7 1 3 8 4 2 5 6 9
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
bool valid(vector<vector<char>>& board, int x, int y) {
char exist[10] = {0};
for (int i = 0; i < 9; ++i)
if (board[x][i] != 'x')
if (!exist[board[x][i]-'0'])
exist[board[x][i]-'0'] = 1;
else
return false;
memset(exist, 0, 10*sizeof(char));
for (int i = 0; i < 9; ++i)
if (board[i][y] != 'x')
if (!exist[board[i][y]-'0'])
exist[board[i][y]-'0'] = 1;
else
return false;
memset(exist, 0, 10*sizeof(char));
int offsetx = x / 3, offsety = y / 3;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
if (board[offsetx*3+i][offsety*3+j] != 'x')
if (!exist[board[offsetx*3+i][offsety*3+j]-'0'])
exist[board[offsetx*3+i][offsety*3+j]-'0'] = 1;
else
return false;
return true;
}
bool SolveSudoku(vector<vector<char>>& board) {
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
if (board[i][j] == 'x') {
for (char ch = '1'; ch <= '9'; ++ch) {
board[i][j] = ch;
if (valid(board, i, j) && SolveSudoku(board))
return true;
board[i][j] = 'x';
}
return false;
}
return true;
}
int main(){
if (freopen("E:\\resume\\Microsoft\\Step 1 Problem and Check\\Sudoku\\SampleInput.txt","r",stdin) == NULL)
printf("open fail\n");
if (freopen("E:\\resume\\Microsoft\\Step 1 Problem and Check\\SudokuOutput.txt","w",stdout) == NULL)
printf("open fail\n");
vector<vector<char> > board(9, vector<char>(9,'x'));
int linenum = 0;
char line[30];
while (!feof(stdin)) {
gets(line);
if (line[0] == '\0') {
linenum = 0;
if(SolveSudoku(board)) {
for (int i = 0; i < 9; ++i){
for (int j = 0; j < 8; ++j)
printf("%c ", board[i][j]);
printf("%c\n", board[i][8]);
}
}
printf("\n");
}
else {
for (int i = 0; i <= 8; ++i)
board[linenum][i] = line[i*2];
++linenum;
}
}
if(SolveSudoku(board)) {
for (int i = 0; i < 9; ++i){
for (int j = 0; j < 8; ++j)
printf("%c ", board[i][j]);
printf("%c\n", board[i][8]);
}
}
return 0;
}
Python Version:
import copy
class Solution:
def IsValid(self, board, row, col, val, n):
baseRow, baseCol = row // 3 * 3, col // 3 * 3
for i in range(n):
if (board[row][i] == val and i != col):
return False
if (board[i][col] == val and i != row):
return False
deltaRow, deltaCol = i // 3, i % 3
if (board[baseRow + deltaRow][baseCol + deltaCol] == val):
return False
return True
def Backtrack(self, board, pos, n, res):
if (res):
return
if (pos == n * n):
res.append(copy.deepcopy(board))
return
row = pos // n
col = pos % n
if (board[row][col] == '.'):
for i in range(1, n + 1):
if (self.IsValid(board, row, col, str(i), n)):
board[row][col] = str(i)
self.Backtrack(board, pos + 1, n, res)
board[row][col] = '.'
else:
self.Backtrack(board, pos + 1, n, res)
def solveSudoku2(self, board):
res = []
self.Backtrack(board, 0, 9, res)
for i in range(9):
for j in range(9):
board[i][j] = res[0][i][j]
def solveSudoku(self, board):
pos = 0
status = [1 for i in range(81)]
for i in range(9):
for j in range(9):
if (board[i][j] != '.'):
status[i * 9 + j] = 0
while (pos > -1):
row, col = pos // 9, pos % 9
if (pos == 81):
return
if (status[pos] > 0): # The original num at pos is not num
while (self.IsValid(board, row, col, str(status[pos]), 9) == False and status[pos] < 10):
status[pos] += 1
if (status[pos] < 10):
board[row][col] = str(status[pos])
pos += 1
else:
board[row][col] = '.'
status[pos] = 1
pos -= 1
while (status[pos] == 0 and pos > 0):
pos -= 1
else:
pos += 1
def solveSudoku3(self, board):
pos = 0
status = [(lambda i : 0 if board[i//9][i%9] == '.' else -1)(i) for i in range(81)]
while (pos > -1):
row, col = pos // 9, pos % 9
if (pos == 81):
return
elif (status[pos] < 0):
pos += 1
elif (status[pos] >= 0 and status[pos] < 9):
status[pos] += 1
if (self.IsValid(board, row, col, str(status[pos]), 9) == True):
board[row][col] = str(status[pos])
pos += 1
elif (status[pos] == 9):
board[row][col] = '.'
status[pos] = 0
pos -= 1
while (status[pos] < 0 and pos > 0):
pos -= 1
if __name__ == '__main__':
s = Solution()
board = \
[['.', '3', '.', '.', '2', '.', '4', '.', '.'],
['9', '.', '.', '.', '4', '.', '8', '.', '.'],
['8', '.', '.', '.', '3', '7', '.', '.', '5'],
['3', '5', '.', '.', '.', '9', '7', '.', '8'],
['.', '.', '8', '4', '.', '3', '1', '.', '.'],
['7', '.', '9', '2', '.', '.', '.', '4', '3'],
['4', '.', '.', '8', '1', '.', '.', '.', '7'],
['.', '.', '5', '.', '9', '.', '.', '.', '2'],
['.', '.', '7', '.', '5', '.', '.', '1', '.']];
s.solveSudoku3(board)
for row in board:
print(row)