Created
March 21, 2015 20:40
-
-
Save grant-park/b7a3d15bbb18857a1f7e to your computer and use it in GitHub Desktop.
It solves sudoku puzzles using backtracking.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def readGrid(filename): | |
f = open(filename) | |
i = 0 | |
grid = [] | |
while i <= 8: | |
rowText = f.readline() | |
rowList = rowText.split() | |
rowList = [int(i) for i in rowList] | |
grid.append(rowList) | |
i += 1 | |
return grid | |
def printGrid(grid): | |
i = 0 | |
while i <= 8: | |
print (grid[i]) | |
i += 1 | |
def solver(grid): | |
x = findEmptySpace(grid) | |
if x == None: | |
return None | |
else: | |
r,c = x | |
def findEmptySpace(g): | |
for row in range(len(g)): | |
for col in range(len(g[row])): | |
if g[row][col] == 0: | |
return row,col | |
def linearSearch(l,v): | |
instances = 0 | |
i = 0 | |
while i < len(l): | |
if l[i] == v: | |
instances += 1 | |
i += 1 | |
else: | |
i += 1 | |
return instances | |
def searchList(l): | |
x = 1 | |
rulesBroken = 0 | |
while x <= 9: | |
z = linearSearch(l,x) | |
if z>1 and z!=0 and z!=None: | |
rulesBroken += 1 | |
x += 1 | |
return rulesBroken | |
def checkList(l): | |
if searchList(l) > 0: | |
return False | |
else: | |
return True | |
def searchCol(g): | |
return(searchRow(rotateGrid(g))) | |
def checkCol(g): | |
if searchCol(g) > 0: | |
return False | |
else: | |
return True | |
def searchRow(g): | |
x = 1 | |
rulesBroken = 0 | |
while x <= 9: | |
for row in range(len(g)): | |
z = linearSearch(g[row],x) | |
if z>1 and z!=0 and z!=None: | |
rulesBroken += 1 | |
x += 1 | |
return rulesBroken | |
def checkRow(g): | |
if searchRow(g) > 0: | |
return False | |
else: | |
return True | |
def rotateGrid(g): | |
newGrid = [[0]*len(g) for _ in range(len(g))] | |
x = 0 | |
while x < 9: | |
y = 0 | |
while y < 9: | |
newGrid[x][y] = g[y][x] | |
y += 1 | |
x += 1 | |
return newGrid | |
def checkSubGrid(g,r,c): | |
subGrid = [] | |
for i in range(r,r + 3): | |
for j in range(c,c + 3): | |
subGrid.append(g[i][j]) | |
return checkList(subGrid) | |
def checkGrid(g): | |
solver(g) | |
if not checkCol(g): | |
return False | |
if not checkRow(g): | |
return False | |
for i in range(0,7,3): | |
for j in range(0,7,3): | |
if not checkSubGrid(g,i,j): | |
return False | |
return True | |
def solve(g): | |
if checkGrid(g): | |
z = findEmptySpace(g) | |
if z == None: | |
return True | |
for i in range(9): | |
for j in range(9): | |
if (g[i][j] == 0): | |
for x in range(1,10): | |
g[i][j] = x | |
#print("") | |
#printGrid(g) | |
#print("") | |
if solve(g): | |
return True | |
else: | |
g[i][j] = 0 | |
return False | |
#The solve function takes forever! Try removing the #s from the solve function and watch it go through every possible combination. | |
#To save time and show if it works, I took a solved sudoku puzzle and simply replaced a couple values with 0s and ran this solver on it. It works I promise! | |
#Here it is: | |
#2 0 6 3 1 8 5 7 4 | |
#5 8 4 9 7 2 6 1 3 | |
#7 1 3 0 4 5 2 8 9 | |
#6 2 5 8 9 7 3 4 1 | |
#9 3 1 4 2 6 8 5 7 | |
#4 7 8 5 3 1 9 2 6 | |
#1 6 7 2 5 3 4 9 8 | |
#8 5 9 7 6 4 1 3 2 | |
#3 4 2 1 8 9 7 6 5 | |
def main(): | |
filename = input('Provide the name of a file that contains a sudoku puzzle: ') | |
grid = readGrid(filename) | |
print("Unsolved puzzle:") | |
printGrid(grid) | |
solved = solve(grid) | |
if solved: | |
print("Solved puzzle: ") | |
printGrid(grid) | |
valid = checkGrid(grid) | |
print("Valid solution? " + str(valid)) | |
else: | |
print("Puzzle unsolvable!") | |
printGrid(grid) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment