Skip to content

Instantly share code, notes, and snippets.

@hayd
Created July 12, 2012 13:07
Show Gist options
  • Save hayd/3097993 to your computer and use it in GitHub Desktop.
Save hayd/3097993 to your computer and use it in GitHub Desktop.
Sudoku checker - checks whether a sudoku grid is allowable, or completable (and if so fills it in)
def check_sudoku(grid):
'''If grid is a valid sudoku board, so far filled-in correctly: returns True
else if grid is a valid sudoku board but has been filled-in incorrectly: returns False
else: returns None
Note: returning True does not imply there is a solution for grid, see solve_sudoku.
'''
def sanity_check():
'''If grid is of the sudoku board format: returns True
else: returns None
'''
if not ( type(grid) is list and len(grid) is 9 ):
return None
for row in grid:
if not ( type(row) is list and len(row) is 9 ):
return None
for element in row:
if not ( element in range(10) and type(element) is int ):
return None
return True
def no_repeats_check(numbers):
return len(numbers) is len(set(numbers))
def row_check(row):
non_zero_in_row = [ x
for x in grid[row]
if x is not 0
]
return no_repeats_check(non_zero_in_row)
def col_check(col):
non_zero_in_col = [ grid[row][col]
for row in range(9)
if grid[row][col] is not 0
]
return no_repeats_check(non_zero_in_col)
def square_check(start_row, start_col):
non_zero_in_square = [ grid[row][col]
for row in range(start_row, start_row+3)
for col in range(start_col, start_col+3)
if grid[row][col] is not 0
]
return no_repeats_check(non_zero_in_square)
if not sanity_check():
return None
for row in range(len(grid)):
if not row_check(row):
return False
for col in range(len(grid)):
if not col_check(col):
return False
for start_row in range(0,9,3):
for start_col in range(0,9,3):
if not square_check(start_row,start_col):
return False
return True
def solve_sudoku(grid):
'''If grid is a valid board and it can be completed: returns an example completed grid
Else if grid is a valid board, but there are no possible solutions: returns False
Else: returns None
'''
check_grid = check_sudoku(grid)
if not check_grid:
return check_grid
#recursion on the empty squares
for row in range(9):
for col in range(9):
if grid[row][col] is 0:
#this is the first empty square
for k in range(1,10):
grid[row][col]=k
solved = solve_sudoku(grid)
if solved:
#we've found a solution recursively
return solved
#reset the empty square, there's no way to fill it in.
grid[row][col]=0
return False
#there are no empty squares and check_sudoku is True, so grid is a solution.
return grid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment