Last active
January 4, 2016 07:59
-
-
Save matt-bernhardt/8592179 to your computer and use it in GitHub Desktop.
A sudoku solver, as I teach myself Python
This file contains 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
# | |
# Translating the sudoku solver from VBScript to Python | |
# | |
# Libraries | |
from xlrd import open_workbook | |
from tempfile import TemporaryFile | |
from xlwt import Workbook | |
import datetime | |
from array import * | |
# global variables | |
log = '' | |
arrPuzzle = array('I',[0,]) | |
arrPotential = array('I',[0,]) | |
intFound = 0 | |
intProgress = 0 | |
def init(): | |
global log | |
# Start up logging | |
timestamp = datetime.datetime.now().strftime("%Y_%m_%d_%H%M%S") | |
# log = open(str(timestamp)+'.txt','w') | |
log = open('logfile.txt','w') | |
log.write('Sudoku solver output\n\n') | |
initPuzzle() | |
initPotential() | |
def initPotential(): | |
global log | |
global arrPotential | |
log.write('Initializing potentials array...\n') | |
arrPotential = [[[0 for x in xrange(9)] for x in xrange(9)] for x in xrange(9)] | |
for row in range(9): | |
for col in range(9): | |
for val in range(9): | |
arrPotential[row][col][val] = val+1 | |
log.write('...potentials initialized\n') | |
log.write('\n') | |
def initPuzzle(): | |
global log | |
global arrPuzzle | |
log.write('Initializing puzzle array...\n') | |
arrPuzzle = [[0 for x in xrange(9)] for x in xrange(9)] | |
log.write('...puzzle initialized\n') | |
log.write('\n') | |
printPuzzleState() | |
def checkCells(): | |
global log | |
global arrPuzzle | |
global arrPotential | |
log.write('Checking cells for unique values\n') | |
for row in range(9): | |
for col in range(9): | |
log.write(' Cell '+str(row)+','+str(col)+' (') | |
printPuzzleLocation(row,col) | |
log.write(') ') | |
intFound = 0 | |
intAvailable = 0 | |
for val in range(1,10): | |
printPotentialLocation(row,col,val-1) | |
if(arrPotential[row][col][val-1]=='#'): | |
intFound = 1 | |
elif(arrPotential[row][col][val-1]!=0): | |
intAvailable += 1 | |
intCandidate = val | |
if(intFound==1): | |
log.write(' Already Found') | |
else: | |
log.write(' '+str(intAvailable)+' candidates') | |
if(intAvailable==1): | |
foundNumber(row,col,intCandidate) | |
log.write('\n') | |
log.write('\n') | |
def checkCols(): | |
global log | |
global arrPuzzle | |
global arrPotential | |
log.write('Checking columns for unique values\n') | |
for col in range(9): | |
log.write('Column '+str(col)+': ') | |
# print column status for easier following in the log | |
for row in range(9): | |
printPuzzleLocation(row,col) | |
log.write("\n") | |
# iterate through each value, looking for any that can only exist in one location in the column | |
for val in range(1,10): | |
log.write(' Potentials for '+str(val)+': ') | |
intFound = 0 | |
intAvailable = 0 | |
for row in range(9): | |
printPotentialLocation(row,col,val-1) | |
if(arrPotential[row][col][val-1]=="#"): | |
intFound = 1 | |
if(arrPotential[row][col][val-1]!=0): | |
intAvailable += 1 | |
intCandidate = row | |
if(intFound==1): | |
log.write(" Already Found") | |
else: | |
log.write(" "+str(intAvailable)+" available") | |
if(intAvailable==1): | |
foundNumber(intCandidate,col,val) | |
log.write("\n") | |
log.write('\n') | |
def checkGroups(): | |
global log | |
global arrPuzzle | |
global arrPotential | |
log.write('Checking groups\n') | |
# iterate through each of the 3x3 local groups rowG,rowC | |
for rowG in range(3): | |
for colG in range(3): | |
log.write(' Group '+str(rowG)+','+str(colG)+'\n') | |
# for each number | |
for val in range(1,10): | |
log.write(' Potential locations for '+str(val)+' ') | |
intFound = 0 | |
intAvailable = 0 | |
for row in range(3): | |
for col in range(3): | |
testRow = (rowG*3)+row | |
testCol = (colG*3)+col | |
printPotentialLocation( testRow , testCol , val-1 ) | |
if(arrPotential[testRow][testCol][val-1]=='#'): | |
intFound = 1 | |
elif(arrPotential[testRow][testCol][val-1]!=0): | |
intAvailable += 1 | |
intCandidateRow = testRow | |
intCandidateCol = testCol | |
log.write(' ') | |
if(intFound==1): | |
log.write(' found') | |
else: | |
log.write(' '+str(intAvailable)+' available') | |
if(intAvailable==1): | |
foundNumber(intCandidateRow,intCandidateCol,val) | |
log.write('\n') | |
log.write('\n') | |
log.write('\n') | |
def checkRows(): | |
global log | |
global arrPuzzle | |
global arrPotential | |
log.write('Checking rows for unique values\n') | |
for row in range(9): | |
log.write('Row '+str(row)+': ') | |
# print row status for easier following in the log | |
for col in range(9): | |
printPuzzleLocation(row,col) | |
log.write("\n") | |
# iterate through each value, looking for any that can only exist in one location in the row | |
for val in range(1,10): | |
log.write(' Potentials for '+str(val)+': ') | |
intFound = 0 | |
intAvailable = 0 | |
for col in range(9): | |
printPotentialLocation(row,col,val-1) | |
if(arrPotential[row][col][val-1]=="#"): | |
intFound = 1 | |
if(arrPotential[row][col][val-1]!=0): | |
intAvailable += 1 | |
intCandidate = col | |
if(intFound==1): | |
log.write(" found") | |
else: | |
log.write(" "+str(intAvailable)+" available") | |
if(intAvailable==1): | |
foundNumber(row,intCandidate,val) | |
log.write("\n") | |
log.write('...done checking rows\n\n') | |
def foundNumber(row,col,val): | |
global log | |
global arrPuzzle | |
global arrPotential | |
global intFound | |
global intProgress | |
log.write("Found "+str(val)+" at "+str(row)+","+str(col)+'\n') | |
intProgress = 1 | |
intFound = intFound + 1 | |
log.write(str(intFound)+" numbers have been found\n") | |
arrPuzzle[row][col] = val | |
printPuzzleState() | |
for x in range(9): | |
arrPotential[x][col][val-1] = 0 | |
arrPotential[row][x][val-1] = 0 | |
arrPotential[row][col][x] = 0 | |
# Need to sort out the local group potential | |
gX = (row//3)*3 | |
gY = (col//3)*3 | |
for gRow in range(3): | |
for gCol in range(3): | |
arrPotential[gX+gRow][gY+gCol][val-1] = 0 | |
# Re-assert arrPotential for this value | |
arrPotential[row][col][val-1] = "#" | |
# printPotentialState() | |
log.write('\n') | |
def loadPuzzle(): | |
global log | |
global arrPuzzle | |
# Load puzzle into array | |
log.write('Loading puzzle...\n') | |
wb = open_workbook('sudoku.xls') | |
sheet = wb.sheet_by_index(0) | |
for row in range(sheet.nrows): | |
for col in range(sheet.ncols): | |
intValue = sheet.cell(row,col).value | |
if(intValue!=''): | |
foundNumber(row,col,int(intValue)) | |
log.write('...puzzle loaded\n\n') | |
# printPuzzleState() | |
def printPuzzleLocation(row,col): | |
global log | |
global arrPuzzle | |
# log.write('('+str(row)+','+str(col)+')') | |
if(arrPuzzle[row][col]!=0): | |
log.write(str(arrPuzzle[row][col])) | |
else: | |
log.write('_') | |
# log.write(' ') | |
def printPotentialLocation(row,col,val): | |
global log | |
global arrPotential | |
if(arrPotential[row][col][val]!=0): | |
log.write(str(arrPotential[row][col][val])) | |
else: | |
log.write('_') | |
def printPuzzleState(): | |
global log | |
global arrPuzzle | |
log.write('Puzzle state...\n') | |
for row in range(len(arrPuzzle)): | |
for col in range(len(arrPuzzle[row])): | |
printPuzzleLocation(row,col) | |
# intValue = '_' if arrPuzzle[row][col]==0 else arrPuzzle[row][col] | |
# log.write(str(intValue)) | |
log.write('\n') | |
log.write('\n') | |
def printPotentialState(): | |
global log | |
global arrPotential | |
global arrPuzzle | |
log.write('Potential state...\n') | |
for row in range(len(arrPotential)): | |
for col in range(len(arrPotential[row])): | |
log.write(str(row)+','+str(col)+': ') | |
printPuzzleLocation(row,col) | |
log.write(' ') | |
for val in range(len(arrPotential[row][col])): | |
printPotentialLocation(row,col,val) | |
log.write('\n') | |
log.write('\n') | |
log.write('\n') | |
for val in range(1,10): | |
log.write("#"+str(val)+"\n") | |
for row in range(9): | |
for col in range(9): | |
printPotentialLocation(row,col,val-1) | |
log.write("\n") | |
log.write("\n") | |
def main(): | |
global log | |
global intProgress | |
init() | |
loadPuzzle() | |
printPotentialState() | |
while intProgress > 0: | |
log.write('\n') | |
log.write('###########################################################\n') | |
log.write('Starting Check Run\n') | |
printPuzzleState() | |
intProgress = 0 | |
checkRows() | |
checkCols() | |
checkCells() | |
checkGroups() | |
log.write('\n') | |
log.write('###########################################################\n') | |
log.write('###########################################################\n') | |
log.write('Puzzle Terminating\n') | |
printPotentialState() | |
printPuzzleState() | |
if __name__ == "__main__": | |
main() | |
# End the script | |
print('Finished!') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment