Python - 简化数独求解器代码
Python - Streamlining sudoku solver code
我正在编写一个脚本来有效地解决数独谜题,但我认为我的代码中有一部分非常丑陋,想要精简。
def square(cell):
rows='ABCDEFGHI'
cols='123456789'
cell_row = cell[0][0]
cell_col = cell[0][1]
if cell_row in rows[0:3]:
x = 'A'
if cell_row in rows[3:6]:
x = 'B'
if cell_row in rows[6:9]:
x = 'C'
if cell_col in cols[0:3]:
y = 'a'
if cell_col in cols[3:6]:
y = 'b'
if cell_col in cols[6:9]:
y = 'c'
return (['Aa','Ab','Ac','Ba','Bb','Bc','Ca','Cb','Cc'].index(x+y))+1
鉴于数独棋盘由 9 个 3x3 正方形组成,此函数的目的是获取棋盘上单元格的坐标和 return 该单元格所属的 3x3 正方形的编号(其中左上角的方块是数字 1,右下角的方块是数字 9)。输入 'cell' 的格式为 ['A5', 6],其中 A 表示行,5 表示列,6 表示单元格的值。
我的代码可以工作,但必须有一种更有效或更美观的方式来实现。如果有任何建议,我将不胜感激。
我能够为您的公式制作一个大大简化的版本。我首先为行和列分配一个基于 0 的索引。然后我使用整数除法只获取有关正方形所在的 3 块的信息。由于向下移动 3 块行会使索引增加 3,而向右移动只会使索引增加 1,因此我乘以行索引除法后减3。这是完成的函数:
def square(cell):
coords = (ord(cell[0][0]) - 65,int(cell[0][1]) - 1)
return 3 * (coords[0] // 3) + coords[1] // 3 + 1
编辑:固定偏移量 1 - 尽管我宁愿从 0 开始,因为您可能希望将返回值用作另一个(子)的索引数组。
因为我不能对其他答案发表评论,所以这里只有我的 2 美分:
cdlane 的回答比此处提供的回答稍慢。如果你摆脱 .lower() (我假设你此时不关心故障保险)并使用 Brien 的答案,你将获得另一个轻微的性能提升。我不知道你多久评估一次 square() 但也许为了性能放弃可读性是值得的 ;)
我认为附加的片段应该可以解决问题。
def square(cell):
# http://www.asciitable.com/
# https://docs.python.org/3/library/functions.html#ord
row = ord(cell[0][0].lower()) - 97
column = int(cell[0][1])-1
return 3*(row//3) + column//3 + 1
就我个人而言,我认为像“65”和“97”这样的神奇数字不会使解决方案更 表现得更好!怎么样:
def square(cell):
rows = 'ABCDEFGHI'
cell_row = rows.index(cell[0][0])
cell_col = int(cell[0][1]) - 1
return 3 * (cell_row // 3) + cell_col // 3 + 1
我正在编写一个脚本来有效地解决数独谜题,但我认为我的代码中有一部分非常丑陋,想要精简。
def square(cell):
rows='ABCDEFGHI'
cols='123456789'
cell_row = cell[0][0]
cell_col = cell[0][1]
if cell_row in rows[0:3]:
x = 'A'
if cell_row in rows[3:6]:
x = 'B'
if cell_row in rows[6:9]:
x = 'C'
if cell_col in cols[0:3]:
y = 'a'
if cell_col in cols[3:6]:
y = 'b'
if cell_col in cols[6:9]:
y = 'c'
return (['Aa','Ab','Ac','Ba','Bb','Bc','Ca','Cb','Cc'].index(x+y))+1
鉴于数独棋盘由 9 个 3x3 正方形组成,此函数的目的是获取棋盘上单元格的坐标和 return 该单元格所属的 3x3 正方形的编号(其中左上角的方块是数字 1,右下角的方块是数字 9)。输入 'cell' 的格式为 ['A5', 6],其中 A 表示行,5 表示列,6 表示单元格的值。
我的代码可以工作,但必须有一种更有效或更美观的方式来实现。如果有任何建议,我将不胜感激。
我能够为您的公式制作一个大大简化的版本。我首先为行和列分配一个基于 0 的索引。然后我使用整数除法只获取有关正方形所在的 3 块的信息。由于向下移动 3 块行会使索引增加 3,而向右移动只会使索引增加 1,因此我乘以行索引除法后减3。这是完成的函数:
def square(cell):
coords = (ord(cell[0][0]) - 65,int(cell[0][1]) - 1)
return 3 * (coords[0] // 3) + coords[1] // 3 + 1
编辑:固定偏移量 1 - 尽管我宁愿从 0 开始,因为您可能希望将返回值用作另一个(子)的索引数组。
因为我不能对其他答案发表评论,所以这里只有我的 2 美分: cdlane 的回答比此处提供的回答稍慢。如果你摆脱 .lower() (我假设你此时不关心故障保险)并使用 Brien 的答案,你将获得另一个轻微的性能提升。我不知道你多久评估一次 square() 但也许为了性能放弃可读性是值得的 ;)
我认为附加的片段应该可以解决问题。
def square(cell):
# http://www.asciitable.com/
# https://docs.python.org/3/library/functions.html#ord
row = ord(cell[0][0].lower()) - 97
column = int(cell[0][1])-1
return 3*(row//3) + column//3 + 1
就我个人而言,我认为像“65”和“97”这样的神奇数字不会使解决方案更 表现得更好!怎么样:
def square(cell):
rows = 'ABCDEFGHI'
cell_row = rows.index(cell[0][0])
cell_col = int(cell[0][1]) - 1
return 3 * (cell_row // 3) + cell_col // 3 + 1