python递归求5!_用Python解数独[6]:递归获得最终答案
import copy
import time
# 求每一行單元格行值域
def valueRange(row):
temp = copy.deepcopy(row)
row_value_range = list(range(1,10))
for i in row:
if i == '':
continue
else:
if row_value_range.count(i) > 0:
row_value_range.remove(i)
else:
continue
for j in range(9):
if temp[j] == '':
temp[j] = row_value_range
else:
temp[j] = [temp[j]]
return temp
# 求數(shù)獨每個單元格行值域
def rowValueRange(soduku):
row_value_range = []
for row in soduku:
row_value_range.append(valueRange(row))
return row_value_range
# 求數(shù)獨每個單元格列值域
def colValueRange(soduku):
soduku_invert = [list(i) for i in list(zip(*soduku))]
temp = rowValueRange(soduku_invert)
s_column_vrange = [list(i) for i in list(zip(*temp))]
return s_column_vrange
# 將一個數(shù)獨數(shù)組轉(zhuǎn)化為數(shù)獨九宮格數(shù)組
def matrix_invert(lista):
listb = [[] for i in range(9)]
for i in range(9):
for j in range(9):
k = i//3
l = j//3
m = k*3 + l
listb[m].append(lista[i][j])
return listb
# 求數(shù)獨每個單元格九宮格值域
def matrixValueRange(soduku):
matrix = matrix_invert(soduku)
temp = rowValueRange(matrix)
matrix_vrange = matrix_invert(temp)
return matrix_vrange
# 三個列表求交集函數(shù)
def inersection(lista,listb,listc):
tempa = []
tempb = []
for i in lista:
for j in listb:
if i == j:
tempa.append(i)
for k in listc:
for l in tempa:
if k == l:
tempb.append(k)
return tempb
# 求數(shù)獨每個單元格總值域
def totalValueRange(soduku):
row_value_range = rowValueRange(soduku)
col_value_range = colValueRange(soduku)
matrix_value_range = matrixValueRange(soduku)
total_value_range = [[] for i in range(9)]
for i in range(9):
for j in range(9):
total_value_range[i].append(inersection(row_value_range[i][j],col_value_range[i][j],matrix_value_range[i][j]))
return total_value_range
# 尋找一行中唯一的值,若該值僅在行值域列表中出現(xiàn)了一次,則其所在單元格取值為該值
def checkUnique(list):
listb = copy.deepcopy(list)
templist = []
for i in listb:
templist.extend(i)
for i in range(len(list)):
for j in list[i]:
if templist.count(j) == 1:
listb[i] = [j]
list = listb
return list
# 尋找每一行的唯一值,更新值域列表
def row_checkUnique(s_row_vrange):
temp = []
for list in s_row_vrange:
temp.append(checkUnique(list))
s_row_vrange = temp
return s_row_vrange
# 檢查值域列表每一行、每一列、每一個九宮格的值域,并尋找唯一值,更新值域列表
def soduku_checkUnique(s_row_vrange):
temp = []
temp_b = []
s_row_vrange = row_checkUnique(s_row_vrange)
for i in list(zip(*s_row_vrange)):# 將數(shù)獨進(jìn)行行列轉(zhuǎn)換,然后對每一列進(jìn)行唯一值檢測
temp.append(list(i))
temp = row_checkUnique(temp)
for i in list(zip(*temp)):
temp_b.append(list(i))
temp_c = matrix_invert(temp_b)# 將數(shù)獨進(jìn)行九宮格轉(zhuǎn)換,然后對每一九宮格進(jìn)行唯一值檢測
temp_c = row_checkUnique(temp_c)
temp_d = matrix_invert(temp_c)
return temp_d
# 將獲得的值域列表轉(zhuǎn)化為一個新的數(shù)獨題目
def generator_soduku(total_value_range):
soduku = [[] for i in range(9)]
for i in range(9):
for j in range(9):
if len(total_value_range[i][j]) == 1:
soduku[i].append(total_value_range[i][j][0])
else:
soduku[i].append('')
return soduku
# 值域列表縮減函數(shù):將值域列表轉(zhuǎn)化為數(shù)獨題目,求新的數(shù)獨題目的值域列表,如此反復(fù)
def reduce_totalValueRange(soduku):
for n in range(100):
total_value_range = totalValueRange(soduku)
total_value_range = soduku_checkUnique(total_value_range)
soduku = generator_soduku(total_value_range)
if total_value_range == totalValueRange(generator_soduku(total_value_range)):
break
return total_value_range
# 檢查行值域列表是否合法
def row_checkRepeat(s_value_range):
for i in s_value_range:
temp = []
for j in i:
if len(j) == 1:
temp.append(j[0])
len_temp = len(temp)
if len_temp != len(list(set(temp))):
return False
return True
# 檢查值域列表是否合法:行檢測,列檢測,九宮格檢測
def soduku_checkRepeat(s_value_range):
temp_col = list(zip(*s_value_range))
temp_matrix = matrix_invert(s_value_range)
return row_checkRepeat(s_value_range) and row_checkRepeat(temp_col) and row_checkRepeat(temp_matrix)
# 計算值域列表取值總的組合數(shù)(各單元格值域長度相乘)
def sodukuRate(s_row_vrange):
rate = 1
for i in s_row_vrange:
for j in i:
rate *= len(j)
return rate
# 主函數(shù),輸入值域列表,如遇到多個取值的單元格,依次嘗試值域里的每個值,通過遞歸的方法檢測值是否正確
def trial(total_value_range):
for i in range(9):
for j in range(9):
if len(total_value_range[i][j]) > 1:
for k in total_value_range[i][j]:
test_value = copy.deepcopy(total_value_range)
test_value[i][j] = [k]
test_value = reduce_totalValueRange(generator_soduku(test_value))
if soduku_checkRepeat(test_value):
if sodukuRate(test_value) == 1:
return test_value
else:
if trial(test_value):
return trial(test_value)
else:
continue
return False
if __name__ == '__main__':
t1 = time.time()
soduku = [[] for i in range(9)]
soduku[0] = ['',1,4,'',9,'','',2,'']
soduku[1] = ['','','','',3,'','','',5]
soduku[2] = [3,8,'','','',2,'',6,'']
soduku[3] = [8,4,'',6,'','','','',2]
soduku[4] = [1,'',5,2,'','',7,'','']
soduku[5] = ['','','','','',7,8,'','']
soduku[6] = [2,'','',4,'','','','',9]
soduku[7] = ['',6,'','','',9,'',5,'']
soduku[8] = ['','','','','','','','','']
a = reduce_totalValueRange(soduku)
for i in trial(a):
print(i)
print("代碼執(zhí)行完畢,用時{}秒".format(round(time.time() - t1,2)))
總結(jié)
以上是生活随笔為你收集整理的python递归求5!_用Python解数独[6]:递归获得最终答案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本田计划 2024 年前在中国、日本等地
- 下一篇: python 关键字大全_一日一技:用实