我正在嘗試構建一個數獨求解器,而不需要太多谷歌搜索。現在,我正在開發一個函式來測驗板子是否有效,稍后我將在回圈中使用它。這是該功能當前的樣子。
def valid(board):
s = 0
for row in board:
if row.count('1') == 1 and row.count('2') == 1 and row.count('3') == 1 and row.count('4') == 1 and row.count('5') == 1 and row.count('6') == 1 and row.count('7') == 1 and row.count('8') == 1 and row.count('9') == 1:
s = 1
for column in range(len(board)):
if i[column].count('1') == 1 and i[column].count('2') == 1 and i[column].count('3') == 1 and i[column].count('4') == 1 and i[column].count('5') == 1 and i[column].count('6') == 1 and i[column].count('7') == 1 and i[column].count('8') == 1 and i[column].count('9') == 1:
s = 1
for r in range(3):
for c in range(3):
print(board[r][c], end = '')
if s == 18:
print('valid')
else:
print('no')
我用來測驗的有效板是這個陣列陣列:
example = [['4','3','5','2','6','9','7','8','1'],['6','8','2','5','7','1','4','9','3'],['1','9','7','8','3','4','5','6','2'],
['8','2','6','1','9','5','3','4','7'],['3','7','4','6','8','2','9','1','5'],['9','5','1','7','4','3','6','2','8'],
['5','1','9','3','2','6','8','7','4'],['2','4','8','9','5','7','1','3','6'], ['7','6','3','4','1','8','2','5','9']]
我確信這不是解決這個問題的最有效方法,但我真的只是想了解這個問題。因此,當一行中每個數字 1-9 出現一次時,我將 1 添加到我的 s 變數中。當每一列都滿足相同的條件時,我也將 1 添加到我的 s 變數中。因此,當每一行和每一列都有數字 1-9 出現一次時,我的 s 變數應該是 18,但這并不能使板子有效,因為我仍然必須檢查每個 3x3 框是否符合他們自己的標準。最后,s 變數應該等于 27 才能使棋盤有效。
我試圖讓 3x3 盒子列印的代碼只會列印第一個 3x3 盒子,我怎樣才能讓它對每個 3x3 盒子重復?誰能幫我解決這個問題?謝謝您的幫助。
編輯:我猜蠻力方法看起來像這樣:
for r in range(3):
for c in range(3):
print(board[r][c], end = '')
print('\n')
for r in range(3):
for c in range(3,6):
print(board[r][c], end = '')
print('\n')
for r in range(3):
for c in range(6,9):
print(board[r][c], end = '')
print('\n')
print('\n')
for r in range(3,6):
for c in range(3):
print(board[r][c], end = '')
print('\n')
for r in range(3,6):
for c in range(3,6):
print(board[r][c], end = '')
print('\n')
for r in range(3,6):
for c in range(6,9):
print(board[r][c], end = '')
print('\n')
print('\n')
for r in range(6,9):
for c in range(3):
print(board[r][c], end = '')
print('\n')
for r in range(6,9):
for c in range(3,6):
print(board[r][c], end = '')
print('\n')
for r in range(6,9):
for c in range(6,9):
print(board[r][c], end = '')
print('\n')
編輯2,我找到了一個更好的方法來做到這一點:
def three(board):
for row in range(0, 9, 3):
for col in range(0, 9, 3):
b = board[row][col] board[row][col 1] board[row][col 2] board[row 1][col] board[row 1][col 1] board[row 1][col 2] board[row 2][col] board[row 2][col 1] board[row 2][col 2]
print(b)
# test if valid...
這給了我這個結果:
435682197
269571834
781493562
826374951
195682743
347915628
519248763
326957418
874136259
^ 這是棋盤內的每 3x3。
uj5u.com熱心網友回復:
每個 3x3 框由三個子串列組成。例如,左上角的框由以下三個子串列組成:
board[0][0:3]
board[1][0:3]
board[2][0:3]
中間的那個看起來像這樣:
board[3][3:6]
board[4][3:6]
board[5][3:6]
要訪問所有 9 個板,您可以回圈所有為 3 的倍數的列,以及所有為 3 的倍數的行。這里每個框只是這三個子串列的串聯:
for row in range(0, 9, 3):
for column in range(0, 9, 3):
box = (board[row][column:column 3]
board[row 1][column:column 3]
board[row 2][column:column 3])
# do something with box
由于您已經有了 a 的解決方案row,因此該解決方案也可以用于這個“扁平”框——它也有 9 個元素。
為了避免代碼重復,最好將行驗證邏輯放在一個小函式中。然后,您可以為每一行、每一列和每個“扁平化”框呼叫該函式。
你做的計數s作業正常,但考慮到一旦你在你的板上發現一個無效的部分,繼續檢查其他部分是沒有用的。在這種情況下,您可以直接跳出并立即退出函式,表明它不是有效的棋盤。如果這樣的退出從未發生并且執行到達函式的末尾,則您不再需要檢查計數器。你沒有早點退出的事實意味著董事會是有效的。所以放下那個計數器。
您的函式最好不要列印結果,而只回傳一個布林值,指示該板是否有效。把它留給呼叫者如何處理這些資訊。
讓我們看看此時函式的樣子:
def valid(board):
def is_complete(line):
return line.count('1') == 1 and line.count('2') == 1 and line.count('3') == 1 and line.count('4') == 1 and line.count('5') == 1 and line.count('6') == 1 and line.count('7') == 1 and line.count('8') == 1 and line.count('9') == 1
for row in board:
if not is_complete(row):
return False
for column in range(9):
line = [row[column] for row in board]
if not is_complete(line):
return False
for row in range(0, 9, 3):
for column in range(0, 9, 3):
line = (board[row][column:column 3]
board[row 1][column:column 3]
board[row 2][column:column 3])
if not is_complete(line):
return False
return True
is_complete為 9 個單元的一部分執行驗證邏輯的那個小功能也是如此。它只回傳布爾運算式,其計算結果為 True of False。
以上作業正常。現在是時候看看is_complete函式中的驗證邏輯了。呼叫count九次效率不高。將所有值收集到一個集合中并驗證該集合是否有 9 個值會更有效。
return False其次,可以使用allorany函式撰寫具有退出點的回圈
這導致以下改進:
def valid(board):
def is_complete(line):
return len(set(line)) == 9
if not all(is_complete(row) for row in board):
return False
if not all(is_complete([row[column] for row in board]) for column in range(9)):
return False
if not all(is_complete(board[row][column:column 3]
board[row 1][column:column 3]
board[row 2][column:column 3])
for row in range(0, 9, 3)
for column in range(0, 9, 3)):
return False
return True
uj5u.com熱心網友回復:
在你的“蠻力”方法中,你有,按順序:
for r in range(0,3)3次,
for r in range(3,6)3次,
for r in range(6,9)3次。
看到圖案了嗎?您可以引入另一個每次增加 3 的變數(或增加 1,但在使用之前將其乘以 3)。
然后,在每個回圈中,您都有完全相同的情況,但使用c而不是r. 您可以為此引入另一個變數。當我說“引入另一個變數”時,它實際上更像是“用自己的索引變數撰寫一個附加回圈。
請注意,您可以像這樣撰寫 for 回圈:
for i in [0, 3, 6]:
uj5u.com熱心網友回復:
在重復事物時,函式總是很好用。你已經理解了主要思想,所以我只是做了一個函式,你可以運行每個組合。
def testbox(row, column):
for r in range(row, row 3):
print()
for c in range(column, column 3):
print(example[r][c], sep=' ', end='')
print('\n')
for r in [0, 3, 6]:
for c in [0, 3, 6]:
testbox(r, c)
uj5u.com熱心網友回復:
我不確定這是否是最好的方法,但我設法做到了:
def validate_part(part_list):
if type(part_list[0]) != int:
part_list = [int(part) for part in part_list]
num_list = list(range(1, 10))
filled = True
for num in num_list:
if num not in part_list:
filled = False
return filled
def valid(board):
col_list = [[] for col in range(1,10)]
square_list = []
check_list = {"row":[], "col":[], "square":[]}
for idx,row in enumerate(board):
for num in range(len(row)):
col_list[idx].append(row[num])
check_list["row"].append(validate_part(row))
for col in col_list:
check_list["col"].append(validate_part(col))
for i in range(0,len(board),3):
part = board[i:i 3]
squares = [[] for s in range(3)]
for row in range(len(part)):
iter = 0
for col in range(0,len(part[row]),3):
squares[iter] = part[row][col:col 3]
iter = 1
square_list = squares
for square in square_list:
check_list["square"].append(validate_part(square))
if False not in check_list["row"] and False not in check_list["col"] and False not in check_list["square"]:
return True
else:
return False
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/514851.html
標籤:Python数组算法数独
上一篇:如何在Typescript中獲取字串中最常見的N個單詞?[復制]
下一篇:std::max_element(vList.begin(),vList.end())回傳的迭代器在清除和更新向量(vList)后更改值
