(Python)检查数独中的3x3,有更好的方法吗?
我在高中的一个总结项目中,搭档给了我这个算法。我希望有人能告诉我有没有更简洁的写法。CB是当前的棋盘位置(全局变量),它是一个列表的列表。
for a in xrange(0, 3):
for b in xrange(0, 3):
for j in xrange(1, 4):
for k in xrange(1, 4):
boxsum += CB[3a + j][3b + k]
if not(boxsum == 45):
return False
boxsum = 0
4 个回答
0
因为总和45并不一定意味着答案是正确的,所以需要用不同的方法来解决。个人来说,我会把这些行合并成一个单一的列表,然后和列表(1,2,...9)进行比较,比如:
#assuming this is your format...
box = [[4,2,3],[1,5,9],[8,7,6]]
def valid_box(box):
check_list = []
for row in box:
check_list += row
return list(range(1,10)) == sorted(check_list)
虽然创建这个列表的代码也可以用列表推导式来写(我不知道哪种方式在处理器上更高效)
def valid_box2(box):
return list(range(1,10)) == sorted( [item for row in box for item in row ] )
合并列表的代码来自于 在Python中将列表的列表变成扁平列表
0
其实有很多更简单的方法来做到这一点。
首先,为什么不使用 numpy
来处理矩阵呢?因为你显然是在处理一个矩阵。我注意到你从“1”开始编号,这有点奇怪,为什么不从“0”开始呢?
import numpy as np
CB = np.array(CB)
def constraint3x3check(CB):
return np.all(np.sum( CB[3*a+1:3*a+3, 3*b+1:3*b+3)==45 for a in range(3) for b in range(3))
0
如果说盒子里的数字加起来是45,这并不意味着里面一定有1到9的所有数字。
比如,你可以把这些数字放进一个集合里,然后检查一下这个集合的长度是不是总是9。
1
首先,下面的代码缩进不正确:
if not(boxsum == 45):
return False
boxsum = 0
(按照现在的缩进方式,这段代码在第一次执行时总是会失败)
其次,在下面这一行:
boxsum += CB[3a + j][3b + k]
你可能想要这样做:
boxsum += CB[3*a + j][3*b + k]
最后,要检查数独游戏中的一个3x3区域,仅仅检查sum
是不够的——你还需要确认1到9的每个数字都出现过(换句话说,就是确保所有数字都在1到9的范围内,并且没有数字出现超过一次)。