我用Python编写了以下Sudoku检查器。我觉得这可以写得更短,也许更有效率。尤其是与square_columns有关的部分。
rows = []
columns = []
squares = []
sudoku_sets = []
for i in range(9):
if i == 0:
row = input("Input the sudoku values row by row.\n")
else:
row = input("")
while len(row) != 9 or not row.isnumeric():
row = input(f"Wrong input. Please insert 9 numbers for row number {i+1}.\n")
rows.append(row)
for i in range(len(rows)):
column = ''
for j in range (len(rows)):
column += rows[j][i]
columns.append(column)
for i in range(0,7,3):
square_columns = ["", "", ""]
for j in range(3):
square_columns[0] += rows[j+i][:3]
square_columns[1] += rows[j+i][3:6]
square_columns[2] += rows[j+i][6:9]
for square in square_columns:
squares.append(square)
sudoku_sets.append(rows)
sudoku_sets.append(columns)
sudoku_sets.append(squares)
def check_sudoku(sets):
for s in sets:
for item in s:
if len(item) == len(set(item)):
continue
else:
return "No"
return "Yes"
print(check_sudoku(sudoku_sets))发布于 2021-11-04 17:13:50
你的代码看起来不错。但仍有一些改进的余地。
开头没有在单个块中定义变量
这是古代C的一种风格,现在的规则是声明变量
由于您(当前)有一个全局范围,所以只适用后一条规则。如果你这样做了
sudoku_sets = []
sudoku_sets.append(rows)
sudoku_sets.append(columns)
sudoku_sets.append(squares)如果sudoku_sets在某个地方被触及,读者不必扫描上面的30行。它所持有的东西是绝对清楚的。
for i in range(0,7,3):有点奇怪。如果你想按3的步骤循环9的范围,就这样写吧。
for i in range(0, 9, 3):该语言旨在允许以一种不需要容易出错的手工编织和篡改的方式编写代码。
您的检查程序只适用于9的平方大小。这可以在文件的早期说明。虽然您的一些代码试图不确定大小,但是有许多行硬编码数字只适用于大小9。
# rows fixed to nine
for i in range(9):
# cols agnostic (but fixed to square)
for i in range(len(rows)):功能是很好的缩小范围和引入更好的可读性。您的代码很好(!)结构成原子任务。但是,我们必须阅读和理解代码才能识别。我们可以对每个块进行改进和注释,也可以通过将块提取到具有良好名称的函数中进行很大的改进。我们做3项功能
def read_rows():
...
return rows
def make_cols(rows):
...
return cols
def make_squares(rows):
...
return squares该函数是独立的,命名为任务并声明依赖项。make_squares用rows做正方形。它不需要columns,也不篡改任何其他变量。当我们使用这些函数时,我们会得到一个可读性很好的顶层代码体。
rows = read_rows()
columns = make_cols(rows)
squares = make_squares(rows)
check_sudoku_sets([rows, columns, squares])此外,令人讨厌的列表首字母缩写也已消失。它们位于指定的函数中,不再干扰顶级作用域。
..。是个坏名声。它不能解释它持有什么。也没有必要这样做,因为行、科尔和方格在检查中没有不同的处理方式。所有三个地区都有“区域”。所以我们可以
regions = rows + columns + squares并将检查简化为
def check_sudoku(regions):
for item in regions:
if len(item) == len(set(item)):
continue
else:
return "No"
return "Yes"这降低了可用性和可测试性。在没有输出的情况下,您几乎在check_sudoku中正确地做到了这一点。但是,当您返回为输出设计的字符串时,仍然存在到输出的耦合。返回bool并将函数重命名为“谓词样式”。
def is_valid_sudoku(regions):
for item in regions:
if len(item) == len(set(item)):
continue
else:
return False
return True可以缩短为
def is_valid_sudoku(regions):
return all((len(item) == len(set(item)) for item in regions))到字符串的转换应在输出中完成。
代码现在看起来像
# this implementation works for size = 9 only
def read_rows():
rows = []
for i in range(9):
if i == 0:
row = input("Input the sudoku values row by row.\n")
else:
row = input("")
while len(row) != 9 or not row.isnumeric():
row = input(f"Wrong input. Please insert 9 numbers for row number {i + 1}.\n")
rows.append(row)
return rows
def make_cols(rows):
columns = []
for i in range(len(rows)):
column = ''
for j in range(len(rows)):
column += rows[j][i]
columns.append(column)
return columns
def make_squares(rows):
squares = []
for i in range(0, 7, 3):
square_columns = ["", "", ""]
for j in range(3):
square_columns[0] += rows[j + i][:3]
square_columns[1] += rows[j + i][3:6]
square_columns[2] += rows[j + i][6:9]
for square in square_columns:
squares.append(square)
return squares
def is_valid_sudoku(regions):
return all((len(item) == len(set(item)) for item in regions))
rows = read_rows()
columns = make_cols(rows)
squares = make_squares(rows)
regions = rows + columns + squares
text = "Yes" if is_valid_sudoku(regions) else "No"
print(text)避免循环索引,但循环元素。在make_cols中,不要像
for j in range(len(rows)):
column += rows[j][i]但要做
for row in rows:
column += row[i]如果您需要索引以及循环,如
for i, e in enumerate(some_list):你关心的是make_squares。一个更简单的实现是按索引遍历所有单元格,并将找到的数字追加到相应的平方。
def make_squares(rows):
squares = ["" for _ in range(9)]
for y, r in enumerate(rows):
for x, e in enumerate(r):
squares[(y//3)*3 + x//3] += e
return squares在您的输入函数中,有第一个输入行的特例--将其从循环中取出,如下所示
def read_rows():
print("Input the sudoku values row by row")
rows = []
for i in range(9):
row = input("")
...此外,您不检查有效的符号完全,你也接受数字'0‘。
https://codereview.stackexchange.com/questions/269669
复制相似问题