python編寫數獨 解題 深度優先搜尋
阿新 • • 發佈:2018-12-15
# -*- coding: cp936 -*- import copy ALLPOSSIBILITIES = set([1,2,3,4,5,6,7,8,9]) ROW = range(9) COL = range(9) def Solution(): arr = [[0,0,0,0,0,0,0,7,6], [6,8,0,0,0,0,0,5,4], [5,3,0,0,0,0,0,0,0], [0,5,9,0,8,6,0,0,0], [1,0,6,0,0,3,0,0,0], [0,0,0,0,0,2,4,0,9], [4,0,3,2,0,0,0,0,0], [0,0,0,7,0,0,5,0,3], [0,0,0,6,3,0,8,4,0]] arr = [[0,0,6,8,5,0,0,0,9], [0,0,2,6,0,1,5,0,0], [5,0,0,0,7,4,2,0,0], [3,0,0,0,6,0,0,0,0], [0,2,0,3,1,0,0,0,0], [8,4,0,7,0,9,6,0,0], [0,0,9,0,0,7,0,3,6], [0,0,0,5,9,3,0,7,0], [0,0,0,0,8,0,0,0,5]] print dfs(arr) print_arr(arr) def print_arr(arr): for ar in arr: print ar def dfs(arr): steps_stack = [] while True: sets = get_map_possibilities(arr) steps = set_value(arr, sets) if steps == None: while len(steps_stack) > 0: step = steps_stack.pop() arr[step[0]][step[1]] = 0 return False elif len(steps) > 0: for step in steps: steps_stack.append(step) print "I can set arr[", step[0], "][", step[1], "] = ", step[2] #print_arr(arr) arr[step[0]][step[1]] = step[2] continue elif len(steps) == 0: break; if is_complete(arr): return True found = False for i in ROW: for j in COL: if arr[i][j] == 0: found = True break if found: break if sets[i][j] == 0: print "What? It can't be any number!" return false #print i, j, sets[i][j] while len(sets[i][j]) > 0: arr[i][j] = sets[i][j].pop() print "I guess arr[", i, "][", j, "] = " , arr[i][j] if dfs(arr): return True print "Wrong Way And Quit!" #print "What? It's not the same!" arr[i][j] = 0 print "I can't find an answer" while len(steps_stack) > 0: step = steps_stack.pop() arr[step[0]][step[1]] = 0 return False def is_complete(arr): for i in ROW: for j in COL: if arr[i][j] == 0: return False return True def set_value(arr, sets_o): sets = copy.deepcopy(sets_o) set_count = 0 steps = [] for i in ROW: for j in COL: if arr[i][j] != 0: continue if len(sets[i][j]) == 0: return None elif len(sets[i][j]) == 1: set_count += 1 steps.append([i, j, sets[i][j].pop()]) return steps else: temp_set = sets[i][j] for s_x in ROW: temp_set -= sets[i][s_x] temp_set -= sets[s_x][j] if len(temp_set) == 0: break pi = i/3*3 pj = j/3*3 for s_i in range(pi, pi+3): for s_j in range(pj, pj+3): temp_set -= sets[s_i][s_j] if len(temp_set) == 1: print "I am avalible ", temp_set steps.append([i, j, temp_set.pop()]) return steps set_count += 1 return steps def get_map_possibilities(arr): row = [] for i in ROW: col = [] for j in COL: col.append(get_possibilities(arr, i, j)) #print i, j, col[-1] row.append(col) return row #x行 y列 def get_possibilities(arr, x, y): if arr[x][y] != 0: return set() possilities = set() for i in ROW: possilities.add(arr[i][y]) possilities.add(arr[x][i]) px = x/3*3 py = y/3*3 for i in range(px, px+3): for j in range(py, py+3): possilities.add(arr[i][j]) return ALLPOSSIBILITIES-possilities if __name__ == "__main__": Solution()