我想编写一些Python代码来检查矩阵是否符合Sudoku规则。我的代码如下:
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循环之后,语句&#34; len(checked)&#34;评估为0,不应该是这样。我不知道发生了什么。
答案 0 :(得分: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
您还需要检查子矩阵。
答案 1 :(得分:0)
问题是你没有正确地为两个内部while循环初始化j
。这是您的代码和指示的修改,使其工作:
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
答案 2 :(得分:0)
您的代码的主要问题是您不会在内部循环结束时将j
重置为零。因此,当您尝试检查第二行(以及后续行)时,j
值太大。当您对列进行测试时会出现同样的问题。
然而,这个逻辑存在其他问题,例如[5,6,4,3,2]
测试没问题,因为它有5个独特的元素,但它们不是正确的元素,它们应该是{{1}的一些排列。 }。类似地,字符串矩阵和包含1.5的矩阵被视为有效而不是无效。
但无论如何,这是一个修复版本,修复了前面提到的[1,2,3,4,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')
这是一种更紧凑,(可能)更快的替代策略,因为它使用Python的快速[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
函数与集合来进行测试。此版本仅认为矩阵有效,如果它包含从1到 n 的整数,其中 n 是矩阵的大小。< / p>
all
<强>输出强>
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
运算符会短路,这意味着如果行无效,则不会检查列。