Skip to content

Instantly share code, notes, and snippets.

@rrampage
Created August 27, 2018 07:11
Show Gist options
  • Save rrampage/ddc6f6fdaa0911493d2edec5cc303271 to your computer and use it in GitHub Desktop.
Save rrampage/ddc6f6fdaa0911493d2edec5cc303271 to your computer and use it in GitHub Desktop.
Solve easy Sudoku (without Backtracking)
# Easy Sudoku Solver - No backtracking
"""
Functions for pretty printing the board
"""
# Pretty print board
def pp(a):
r = len(a)
for x in range(r):
print(''.join((str(e) for e in a[x])))
# Pretty print the neighborhood of a cell
def pn(i,j):
b = [['-' for x in range(9)] for y in range(9)]
b[i][j] = 'O'
for x,y in N[(i,j)]:
b[x][y] = 'X'
pp(b)
def box(i,j):
# Calculate the "box number" from row and column
return 3*(i//3) + (j//3)
def box_pairs(b):
i = 3*(b // 3)
j = 3*(b % 3)
return [(i,j),(i,j+1),(i,j+2),(i+1,j),(i+1,j+1),(i+1,j+2),(i+2,j),(i+2,j+1),(i+2,j+2)]
def neighbors():
# Generate all neighbor pairs for the 81 cells
boxes = [box_pairs(x) for x in range(9)] # Generate all possible pairs for each "box number"
ng = {}
for i,j in PAIRS:
s = set(boxes[box(i,j)]+[(i,x) for x in range(9)]+[(x,j) for x in range(9)])
s.remove((i,j))
ng[(i,j)] = s
return ng
def dup(a):
# Utility method to create duplicate of board
return [list(a[i]) for i in range(len(a))]
def check(a):
# Checks if Sudoku is solved
for x in range(9):
if REF != set(a[x]) or REF != {a[i][x] for i in range(9)} or REF != {a[i][j] for i,j in box_pairs(x)}:
return False
return True
def allowed(a, i, j):
# Returns allowed values for a particular cell
if a[i][j] != 0: # If already filled, ignore
return set()
s = {a[x][y] for x,y in N[(i,j)] if a[x][y] != 0} #values of neighbors
return REF - s
def instance(a):
# Solves easy Sudoku
if check(a):
return a
s = {}
b = dup(a)
for i,j in PAIRS:
e = allowed(a,i,j)
if len(e) == 1:
v = e.pop()
b[i][j] = v
s[(i,j)] = e
if a == b:
# If no progress has been made, return
return b
return instance(b)
REF = set(range(1,10)) # The Set we use to check if a row/col/box is filled correctly
PAIRS = [(i,j) for i in range(9) for j in range(9)] # Generate all pairs from 0 to 9
N = neighbors() # One time call, generate and store all possible neighbors for a cell
# A test instance
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]]
# Pretty print completed Sudoku
pp(instance(puzzle))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment