# 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))