有段时间没写程序了,用Python写了个解数独的程序练练手~ 解数独的程序,不到80行 #!encoding:utf8 # file solve_sudoku.py sqrULCorners = [(0,0),(0,3),(0,6),(3,0),(3,3),(3,6),(6,0),(6,3),(6,6)] sqrOffsets = [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)] digits = range(1,10) def isValidSolution(solution): state = initState(solution) for i in range(9): for j in range(9): r = getPossibleDigitsAt(i, j, state) if solution[i][j] not in r: return False return True def solvePuzzle(puzzle): state = initState(puzzle) if solve(state, 0, 0) == True: solution = state2Solution(state) return solution return None def solve(state, i, j): if i > 8: return True i2,j2 = nextCell(i, j) if state[i][j][0] == 0: for d in getPossibleDigitsAt(i, j, state): state[i][j][0] = d if solve(state, i2, j2) == True: return True state[i][j][0] = 0 return False else: return solve(state, i2, j2) def getSqrULCorner(i, j): return sqrULCorners[3 * (i / 3) + (j / 3)] def getPossibleDigitsAt(i, j, state): occurs = 10 * [False] ulCorner = getSqrULCorner(i, j) for k in range(9): if k != j: occurs[state[i][k][0]] = True if k != i: occurs[state[k][j][0]] = True x = ulCorner[0]+sqrOffsets[k][0] y = ulCorner[1]+sqrOffsets[k][1] if x != i or y != j: occurs[state[x][y][0]] = True possibleDigits = [] for k in digits: if occurs[k] == False: possibleDigits = possibleDigits + [k] return possibleDigits def nextCell(i, j): if j == 8: return i + 1, 0 else: return i, j + 1 def initState(puzzle): state = [[([0] + 9 * [False]) for col in range(9)] for row in range(9)] for i in range(9): for j in range(9): state[i][j][0] = puzzle[i][j] return state def state2Solution(state): solution = [[0 for col in range(9)] forrow in range(9)] for i in range(9): for j in range(9): solution[i][j] = state[i][j][0] return solution def printTable(table): for i in range(9): for j in range(9): print table[i][j], print PyUnit的测试程序,不到60行 #!encoding:utf8 #file test_solve_sudoku.py import unittest from solve_sudoku import * 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] ] invalidSolution / = [[5,3,4,6,7,8,9,1,2], / [6,7,2,1,9,5,3,4,8], / [1,9,8,3,4,2,5,6,7], / [8,5,9,7,6,1,4,2,3], / [4,2,6,8,5,3,7,9,1], / [7,1,3,9,2,4,8,5,6], / [9,6,1,5,3,7,2,8,4], / [2,8,7,4,1,9,9,3,5], / [3,4,5,2,8,6,1,7,9] ] validSolution / = [[5,3,4,6,7,8,9,1,2], / [6,7,2,1,9,5,3,4,8], / [1,9,8,3,4,2,5,6,7], / [8,5,9,7,6,1,4,2,3], / [4,2,6,8,5,3,7,9,1], / [7,1,3,9,2,4,8,5,6], / [9,6,1,5,3,7,2,8,4], / [2,8,7,4,1,9,6,3,5], / [3,4,5,2,8,6,1,7,9] ] class ValidateTestCase(unittest.TestCase): def testValidSolution(self): print "testValidSolution..." print "solution..." printTable(invalidSolution) assert isValidSolution(invalidSolution) == False print "is invalid." print "solution..." printTable(validSolution) assert isValidSolution(validSolution) == True print "is valid" def testSolvePuzzle(self): print "The puzzle is" printTable(puzzle) print "Solving..." solution = solvePuzzle(puzzle) print "Done." print "The solution is" if solution != None: printTable(solution) assert isValidSolution(solution) == True if __name__ == "__main__": unittest.main()