This is my naive approach on implementing a Sudoku solver, which is okay for simple Sudokus like this:
puzzle = [[5,3,0,0,7,0,0,0,0],
[6,0,0,1,9,5,0,0,0],
[0,9,8,0,0,0,0,6,0],
[8,0,0,0,6,0,0,0,3],
[4,0,0,8,0,3,0,0,1],
[7,0,0,0,2,0,0,0,6],
[0,6,0,0,0,0,2,8,0],
[0,0,0,4,1,9,0,0,5],
[0,0,0,0,8,0,0,7,9]]
However, it is rather slow for hard Sudokus like this:
[[9, 0, 0, 0, 8, 0, 0, 0, 1],
[0, 0, 0, 4, 0, 6, 0, 0, 0],
[0, 0, 5, 0, 7, 0, 3, 0, 0],
[0, 6, 0, 0, 0, 0, 0, 4, 0],
[4, 0, 1, 0, 6, 0, 5, 0, 8],
[0, 9, 0, 0, 0, 0, 0, 2, 0],
[0, 0, 7, 0, 3, 0, 2, 0, 0],
[0, 0, 0, 7, 0, 5, 0, 0, 0],
[1, 0, 0, 0, 4, 0, 0, 0, 7]]
The challenge description is:
Write a function that will solve a 9x9 Sudoku puzzle. The function will take one argument consisting of the 2D puzzle array, with the value 0 representing an unknown square.
The Sudokus tested against your function will be "insane" and can have multiple solutions. The solution only needs to give one valid solution in the case of the multiple solution sodoku.
It might require some sort of brute force.
Tests: 100 random tests and 5 assertions per test
Time limit: 12sec
My code:
def sudoku(board):
(x, y) = find_empty_cell(board)
if (x, y) == (-1, -1):
return True
for i in {1,2,3,4,5,6,7,8,9}:
if valid(x,y,i,board):
board[x][y] = i
if sudoku(board):
return board
board[x][y] = 0
def valid(x,y,n,board):
#check row and column
for i in range(9):
if board[x][i] == n or board[i][y] == n:
return False
#check box
new_x = x//3 * 3
new_y = y//3 * 3
for i in range(3):
for j in range(3):
if board[new_x + i][new_y + j] == n:
return False
return True
def find_empty_cell(board):
for i in range(9):
for j in range(9):
if board[i][j] == 0:
return (i,j)
return (-1,-1)
I am trying to succeed in passing a coding challenge in a competitive platform, which my specific code times out.