#!/usr/bin/env python #================================================================ # Sudoku puzzle solver. For documentation, see: # http://www.nmt.edu/tcc/help/lang/python/sudoku/ #---------------------------------------------------------------- #================================================================ # Imports #---------------------------------------------------------------- import sys import time import sudosolver # - - - m a i n - - - def main(): """sudoku main program """ #-- 1 -- argList = sys.argv[1:] #-- 2 -- # [ if argList is empty -> # sys.stderr +:= error message # else -> # sys.stdout +:= solutions to valid puzzles named in # argList # sys.stderr +:= error messages about invalid puzzles # named in argList ] if len(argList) == 0: message ( "*** You must supply names of " "at least one sudoku puzzle file.\n" ) else: for arg in argList: solveFile ( arg ) # - - - m e s s a g e - - - def message ( * L ): """Write a message to sys.stderr. [ L is a list of strings -> sys.stderr +:= concatenation of L ] """ sys.stderr.write ( "*** %s\n" % "".join(L) ) # - - - f a t a l - - - def fatal ( *L ): """Write a message and terminate. [ L is a list of strings -> sys.stderr +:= concatenation of L stop execution ] """ message ( *L ) sys.exit(1) # - - - s o l v e F i l e - - - def solveFile ( fileName ): """Try to solve one puzzle. [ fileName is a string -> if fileName names a readable, valid sudoku puzzle file -> sys.stdout +:= solution(s) to that puzzle if any sys.stderr +:= message if there are no solutions else -> sys.stderr +:= error message about a bad puzzle ] """ #-- 1 -- # [ if fileName names a readable file -> # rawPuzzle := contents of that file # else -> # sys.stderr +:= error message # return ] try: inFile = open ( fileName ) rawPuzzle = inFile.read() except IOError, detail: message ( "*** Can't open file '%s' for reading. %s\n" % (fileName, detail) ) return #-- 2 -- # [ if rawPuzzle is a valid sudoku puzzle -> # solver := an instance of SudokuSolver to solve # rawPuzzle that will call solutionFound when it # finds a solution # else -> # sys.stderr +:= error message # return ] try: solver = sudosolver.SudokuSolver ( rawPuzzle, solutionFound ) except ValueError, detail: message ( "Invalid puzzle: %s" % detail ) return #-- 3 -- # [ sys.stdout +:= (fileName) + (puzzle in its initial # state ] separator = "=" * 9 print "\n%s %s %s" % (separator, fileName, separator) solver.write ( sys.stdout ) #-- 4 -- # [ sys.stdout +:= solutions to solver, if any ] startClock = time.clock() solver.solve() endClock = time.clock() #-- 5 -- # [ sys.stdout +:= report on the number of solutions in # solver ] print "\nNumber of solutions found:", solver.nSolutions print "Elapsed cpu time: %.2f seconds." % (endClock-startClock) # - - - s o l u t i o n F o u n d - - - def solutionFound ( solver ): """Report a successful solution of the puzzle. [ sys.stdout +:= display of the state of solver ] """ print "\n--- Solution #%d:" % solver.nSolutions solver.write ( sys.stdout ) #================================================================ # Epilogue #---------------------------------------------------------------- if __name__ == "__main__": main()