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.
A sudoku puzzle...
...and its solution numbers marked in red.
Use backtracking strategy to solve this problem. First find a blank spot. Then find available candidate values. And go to find next blank spot. If the current solution is unresolvable, go back on step and try another one.
C++ Code:
/*
* func: find_available
* goal: find available candidates for current spot
* @param candidates: candidates set
* @param board: current sudoku board
* @param row: row index
* @param column: column index
* return:
*/
void find_available(vector<bool>& candidates, const vector<vector<char> > &board, int row, int column){
for(int i = 0; i < 9; ++i){
if(board[i][column] != '.'){
candidates[board[i][column] - '1'] = false;
}
if(board[row][i] != '.'){
candidates[board[row][i]-'1'] = false;
}
if(board[row/3*3 + i/3][column/3*3 + i%3] != '.'){
candidates[board[row/3*3 + i/3][column/3*3 + i%3] - '1'] = false;
}
}
}
/*
* func: solve_sudoku_helper
* goal: solve the sudoku problem in backtracking
* @param board: the sudoku board
* @param row: current row index
* @param column: current column index
* return: true or false
*/
bool solve_sudoku_helper(vector<vector<char> > &board, int row, int column){
//Find the next empty position
while(row < 9 && board[row][column] != '.'){
row = (column == 8) ? row + 1 : row;
column = (column + 1) % 9;
}
if(row == 9){
return true;
}
//Find available candidate for the current spot
vector<bool> candidates(9, true);
find_available(candidates, board, row, column);
for(int i = 0; i < 9; i++){
if(candidates[i]){
board[row][column] = i + '1';
if(solve_sudoku_helper(board, row, column)){
return true;
}
}
}
board[row][column] = '.';
return false;
}
/*
* func: solve_sudoku
* goal: solve the given sudoku problem
* @param board: input sudoku board
* return:
*/
void solve_sudoku(vector<vector<char> > &board){
solve_sudoku_helper(board, 0, 0);
}
For Python code, we can just convert the C++ code and it can pass the test. Here I introduced another solution which looks simpler but cannot pass because of time limit.
def same_row(i, j):
return i/9 == j/9
def same_col(i, j):
return (i-j) % 9 == 0
def same_block(i, j):
return i/27 == j/27 and i%9/3 == j%9/3
def solve_sudoku_helper(board_list, board):
spot = board_list.find('.')
if spot == -1:
for i in xrange(9):
board[i] = board_list[i*9: (i+1)*9]
return
excluded_numbers = set()
for i in range(81):
if same_row(spot, i) or same_col(spot, i) or same_block(spot, i):
excluded_numbers.add(board_list[i])
for candidate in '123456789':
if candidate not in excluded_numbers:
solve_sudoku_helper(board_list[:spot] + candidate + board_list[spot+1:], board)
# func: solve sudoku problem
# @param board: current sudoku board
# @return:
def solve_sudoku(board):
boardlist = ''.join(x for row in board for x in row)
solve_sudoku_helper(boardlist, board)
Reference Link:
1.Simple Sudoku solver in python | Bite Sized Python Tips: http://freepythontips.wordpress.com/2013/09/01/sudoku-solver-in-python/
No comments:
Post a Comment