2016-09-26 23 views
-1

我想編寫一些Python代碼來檢查矩陣是否符合數獨規則。我的代碼如下:列表長度檢查在數獨檢查器中不起作用

correct = [[1,2,3], 
      [2,3,1], 
      [3,1,2]] 

incorrect = [[1,2,3,4], 
      [2,3,1,3], 
      [3,1,2,3], 
      [4,4,4,4]] 

incorrect2 = [[1,2,3,4], 
      [2,3,1,4], 
      [4,1,2,3], 
      [3,4,1,2]] 

incorrect3 = [[1,2,3,4,5], 
       [2,3,1,5,6], 
       [4,5,2,1,3], 
       [3,4,5,2,1], 
       [5,6,4,3,2]] 

incorrect4 = [['a','b','c'], 
       ['b','c','a'], 
       ['c','a','b']] 

incorrect5 = [ [1, 1.5], 
       [1.5, 1]] 

def check_sudoku(matrix): 
    n = len(matrix) 
    # check each row 
    i, j = 0, 0 
    while i < n: 
     checked = [] 
     while j < n: 
      if matrix[i][j] not in checked: 
       checked.append(matrix[i][j]) 
      j += 1 
     if len(checked) < n: 
      return False 
     i += 1 
    # check each column 
    i, j = 0, 0 
    while i < n: 
     checked = [] 
     while j < n: 
      if matrix[j][i] not in checked: 
       len(checked) 
       checked.append(matrix[j][i]) 
      j += 1 
     if len(checked) < n: 
      return False 
     i += 1 

    return True 

# the output should look like this: 
print(check_sudoku(incorrect)) 
#>>> False 

print(check_sudoku(correct)) 
#>>> True 

print(check_sudoku(incorrect2)) 
#>>> False 

print(check_sudoku(incorrect3)) 
#>>> False 

print(check_sudoku(incorrect4)) 
#>>> False 

print(check_sudoku(incorrect5)) 
#>>> False 

但是,if語句中存在一個奇怪的問題。在兩個內部while循環之後,語句「len(checked)」的計算結果爲0,不應該如此。我不知道發生了什麼事。

+0

「後內循環」哪一個? –

+0

內部while循環 –

+0

您應該考慮將您的'check_sudoku'分解爲更多功能。 – PhilipB

回答

0

與您的代碼的主要問題是,你不會在內部循環結束時復位j爲零。因此,當您嘗試檢查第二行(和後續行)時,j值太大。測試列時發生同樣的問題。

但是,這個邏輯還有其他問題,例如[5,6,4,3,2]測試沒問題,因爲它有5個獨特的元素,但它們不是正確的元素,它們應該是[1,2,3,4,5]的一些排列組合。類似地,字符串矩陣和包含1.5的矩陣被視爲有效而非無效。

但無論如何,這是一個修復版本,修復了前面提到的j初始化問題。

grids = [ 
    [[1,2,3], 
    [2,3,1], 
    [3,1,2]], 

    [[1,2,3,4], 
    [2,3,1,3], 
    [3,1,2,3], 
    [4,4,4,4]], 

    [[1,2,3,4], 
    [2,3,1,4], 
    [4,1,2,3], 
    [3,4,1,2]], 

    [[1,2,3,4,5], 
    [2,3,1,5,6], 
    [4,5,2,1,3], 
    [3,4,5,2,1], 
    [5,6,4,3,2]], 

    [['a','b','c'], 
    ['b','c','a'], 
    ['c','a','b']], 

    [[1, 1.5], 
    [1.5, 1]], 
] 

def check_sudoku(matrix): 
    n = len(matrix) 
    # check each row 
    i = 0 
    while i < n: 
     checked = [] 
     j = 0 
     while j < n: 
      if matrix[i][j] not in checked: 
       checked.append(matrix[i][j]) 
      j += 1 
     if len(checked) < n: 
      return False 
     i += 1 
    # check each column 
    i = 0 
    while i < n: 
     checked = [] 
     j = 0 
     while j < n: 
      if matrix[j][i] not in checked: 
       checked.append(matrix[j][i]) 
      j += 1 
     if len(checked) < n: 
      return False 
     i += 1 

    return True 

for g in grids: 
    for row in g: 
     print(row) 
    print(check_sudoku(g), end='\n\n') 

輸出

[1, 2, 3] 
[2, 3, 1] 
[3, 1, 2] 
True 

[1, 2, 3, 4] 
[2, 3, 1, 3] 
[3, 1, 2, 3] 
[4, 4, 4, 4] 
False 

[1, 2, 3, 4] 
[2, 3, 1, 4] 
[4, 1, 2, 3] 
[3, 4, 1, 2] 
False 

[1, 2, 3, 4, 5] 
[2, 3, 1, 5, 6] 
[4, 5, 2, 1, 3] 
[3, 4, 5, 2, 1] 
[5, 6, 4, 3, 2] 
True 

['a', 'b', 'c'] 
['b', 'c', 'a'] 
['c', 'a', 'b'] 
True 

[1, 1.5] 
[1.5, 1] 
True 

下面是一個替代策略這是更緊湊,並且(可能)更快,因爲它使用Python快速all功能結合套做的測試。該版本只有認爲矩陣有效,如果它包含從1到的整數n,其中n是矩陣的大小。

grids = [ 
    [[1,2,3], 
    [2,3,1], 
    [3,1,2]], 

    [[1,2,3,4], 
    [2,3,1,3], 
    [3,1,2,3], 
    [4,4,4,4]], 

    [[1,2,3,4], 
    [2,3,1,4], 
    [4,1,2,3], 
    [3,4,1,2]], 

    [[1,2,3,4,5], 
    [2,3,1,5,6], 
    [4,5,2,1,3], 
    [3,4,5,2,1], 
    [5,6,4,3,2]], 

    [['a','b','c'], 
    ['b','c','a'], 
    ['c','a','b']], 

    [[1, 1.5], 
    [1.5, 1]], 
] 

def check_sudoku(matrix): 
    full = set(range(1, len(matrix) + 1)) 
    return (all(set(row) == full for row in matrix) 
     and all(set(row) == full for row in zip(*matrix))) 

for g in grids: 
    for row in g: 
     print(row) 
    print(check_sudoku(g), end='\n\n') 

輸出

[1, 2, 3] 
[2, 3, 1] 
[3, 1, 2] 
True 

[1, 2, 3, 4] 
[2, 3, 1, 3] 
[3, 1, 2, 3] 
[4, 4, 4, 4] 
False 

[1, 2, 3, 4] 
[2, 3, 1, 4] 
[4, 1, 2, 3] 
[3, 4, 1, 2] 
False 

[1, 2, 3, 4, 5] 
[2, 3, 1, 5, 6] 
[4, 5, 2, 1, 3] 
[3, 4, 5, 2, 1] 
[5, 6, 4, 3, 2] 
False 

['a', 'b', 'c'] 
['b', 'c', 'a'] 
['c', 'a', 'b'] 
False 

[1, 1.5] 
[1.5, 1] 
False 

這一部分:

all(set(row) == full for row in zip(*matrix)) 

驗證列是有效的,因爲zip(*matrix)實質上創建的matrix轉置版本。

all函數相當高效,只要遇到錯誤結果就立即停止測試。在類似的說明中,and運算符會短路,這意味着如果行無效,則不會檢查列。

0

您不會在內循環(兩個內循環)中調零j變量。

i, j = 0, 0 
while i < n: 
    checked = [] 
    j = 0 # you need set j to zero in each run 
      # if you don't do this: j will be equal to n in second run 
    while j < n: 
     if matrix[i][j] not in checked: 
      checked.append(matrix[i][j]) 
     j += 1 
    if len(checked) < n: 
     return False 
    i += 1 

此外,你需要檢查子矩陣。

+0

您不必檢查sudokus中的對角線。只是除了行和列以外的子矩陣。並且你的代碼返回'[False,True,False,True,True,True]' –

+0

謝謝,我現在明白了。 –

+0

@ Ev.Kounis測驗只需要我們檢查列和行。謝謝你。 –

0

問題是你沒有初始化j正確的兩個內部while循環。這裏是你的代碼,並指示修改,使其工作:

def check_sudoku(matrix): 
    n = len(matrix) 
    # check each row 
# i, j = 0, 0 
    i = 0 
    while i < n: 
     j = 0 # added 
     checked = [] 
     while j < n: 
      if matrix[i][j] not in checked: 
       checked.append(matrix[i][j]) 
      j += 1 
     if len(checked) < n: 
      return False 
     i += 1 
    # check each column 
# i, j = 0, 0 
    i = 0 
    while i < n: 
     j = 0 # added 
     checked = [] 
     while j < n: 
      if matrix[j][i] not in checked: 
       checked.append(matrix[j][i]) 
      j += 1 
     if len(checked) < n: 
      return False 
     i += 1 

    return True