defnewTemp(): """ 创建一个空数独 调用该函数会返回一个9*9的二维列表,每个元素都是一个数字元素 :return: """ array = [] for i inrange(9): array.append([]) for j inrange(9): array[i].append([0, True]) return array
# 这个函数在逻辑上是调用api的人写的,个人建议放在下面,即api函数应放一起,这个函数要单独放 defstartWrite(array): """开始出题""" num = int(input("请输入初始数的数量:")) for i inrange(num): print(f"请输入第{i+1}个数")
num = int(input("您要输入的数字是多少?")) y = int(input("输入的数字在第几行?")) x = int(input("第几列?")) array[y - 1][x - 1][0] = num array[y - 1][x - 1][1] = False printSudokuTable(array) choice = input("数据输入完毕,开始破解输入1,修改输入数据请输入任意……") if choice != '1': whileTrue: num = int(input("您要修改的数字是多少?")) y = int(input("输入的数字在第几行?")) x = int(input("第几列?")) array[y - 1][x - 1][0] = num array[y - 1][x - 1][1] = False printSudokuTable(array) do = input("是否开始破解?是请输入1,否则输入任意:") if do == '1': break return array
defisTrue(array): """ 传入一个数独二维列表,判断其是否合法,若合法则返回真,否则返回假 :param array: 表示数独的二维列表 :return: """ # 判断所有行 for i inrange(9): # 遍历每一行: for j inrange(9): # 遍历1-9数字,看是否超过1: num = j + 1 numTimes = 0 for k inrange(9): # 遍历一行里的9个位置: if array[i][k][0] == num: numTimes += 1 if numTimes > 1: returnFalse
# 判断所有列 for i inrange(9): # 遍历每一列: for j inrange(9): # 遍历1-9数字,看是否超过1: num = j + 1 numTimes = 0 for k inrange(9): # 遍历一列里的9个位置: if array[k][i][0] == num: numTimes += 1 if numTimes > 1: returnFalse
# 判断所有宫 for i inrange(3): # 遍历每一行宫 # y = i * 3 for j inrange(3): # 在每一行宫里遍历每一个宫 # x = i * 3 for k inrange(9): # 在每一个宫里遍历每一个数字: num = k + 1 numTimes = 0 for m inrange(3): # 在每一个宫里遍历3行 # y += m for n inrange(3): # 在每一个宫的每一行里遍历三个位置: # x += n # if array[y][x][0] == num: if array[i * 3 + m][j * 3 + n][0] == num: numTimes += 1 if numTimes > 1: returnFalse returnTrue
defprintSudoku(array): """打印数独""" for i inrange(3): # 三个大横段 for j inrange(3): # 三横行紧凑 for k inrange(3): # 横行里每三个数 for m inrange(3): # 每一个数 print(array[i*3+j][k*3+m][0], end=" ") print(' ', end="") print() print()
defprintSudokuTable(array): """打印当前整个数独--有边框的方式""" print("┏━━━━━━━┳━━━━━━━┳━━━━━━━┓") for i inrange(3): # 三个大横段 for j inrange(3): # 每一行 print('┃ ', end="") for k inrange(3): # 横行里每个组 for m inrange(3): # 每一个数 print(array[i*3+j][k*3+m][0], end=" ") print('┃ ', end="") if j != 3-1: print('') if i != 3-1: print() print("┣━━━━━━━╋━━━━━━━╋━━━━━━━┫") print() print("┗━━━━━━━┻━━━━━━━┻━━━━━━━┛")
defcrack(soduArray): """破解数独""" # 先建立一个一维数组,存放数独可写位置 # 此数组里的对象是数独列表里的对象,所以可以直接引用,同步更改 writeArray = [] for i inrange(len(soduArray)): for j inrange(len(soduArray[i])): if soduArray[i][j][1]: writeArray.append(soduArray[i][j]) x = 0 n = 1 step = 0 whileTrue: print(step) printSudokuTable(soduArray)
writeArray[x][0] = n if isTrue(soduArray): step += 1 if x == len(writeArray)-1: print("破解成功") printSudokuTable(soduArray) break else: x += 1 n = 1 continue else: whileTrue: step += 1 if n >= 9: if x == 0: exit("无解") else: writeArray[x][0] = 0 x -= 1 n = writeArray[x][0] n += 1 continue else: n += 1 break print(f"总共试了{step}个数")