我正在尝试创建一个搜索魔术方块的程序。
class square:
def __init__(self, n1,n2,n3,n4,n5,n6,n7,n8,n9):
self.row1 = n1+n2+n3
self.row2 = n4+n5+n6
self.row3 = n7+n8+n9
self.col1 = n1+n4+n7
self.col2 = n2+n5+n8
self.col3 = n3+n6+n9
self.diag1 = n1+n5+n9
self.diag2 = n3+n5+n7
self.n1 = n1
self.n2 = n2
self.n3 = n3
self.n4 = n4
self.n5 = n5
self.n6 = n6
self.n7 = n7
self.n8 = n8
self.n9 = n9
def checkMagic(self):
if (self.row1==self.row2==self.row3==self.col1==self.col2==self.col3==self.diag1==self.diag2):
print("magic square found")
print(str(self.n1) + " " + str(self.n2) + " " + str(self.n3))
print(str(self.n4) + " " + str(self.n5) + " " + str(self.n6))
print(str(self.n7) + " " + str(self.n8) + " " + str(self.n9))
到目前为止,这将创建一个正方形并检查它是否是魔术。我想遍历并创建/检查所有可能的幻方,以找到某个整数k下的数字。例如,如果我将其设置为k = 10,它应该找到这个平方:
square(2,7,6,9,5,1,4,3,8)
对于想了解更多信息的人,这里有一些有关魔方的更多信息: http://mathworld.wolfram.com/MagicSquare.html
答案 0 :(得分:1)
这是一个更通用的功能,用于检查以数字列表表示的正方形是否是魔术:
def is_magic_square(cells):
width = int(len(cells) ** .5)
# Start with 1st diagonal total
total = sum(cells[::width+1])
# Check 2nd diagonal
if sum(cells[width-1:len(cells)-1:width-1]) != total:
return False
# Check row totals
for i in range(0, len(cells)-1, width):
if sum(cells[i:i+width]) != total:
return False
# Check column totals
for i in range(width):
if sum(cells[i::width]) != total:
return False
return True
然后您可以像这样检查所有具有给定宽度的正方形。
def find_magic_squares(width):
for sequence in itertools.permutations(range(1, width*width+1)):
if is_magic_square(sequence):
print("Found magic square:", sequence)
这显然仍然是蛮力的方法,并且宽度大于3时会变得非常慢。但是这可能是一个有用的开始方法。
答案 1 :(得分:1)
用于生成9个单元格总计c
的魔方的算法
编辑,要考虑到@Stuart评论的 不同的数字 功能。
这些将是方程组和描述它的矩阵:
现在,使用Gaussian elimination进行求解,方程式最终将简化为:
x1=2*c/3-x9
x2=2*c/3-x8
x3=(-c)/3+x8+x9
x4=(-2*c)/3+x8+2*x9
x5=c/3
x6=4*c/3-x8-2*x9
x7=c-x8-x9
x8=x8
x9=x9
现在考虑到所有单元格都必须为integers greater than 0
,您只需尝试从x8
到{{1}的x9
和1
单元格的替换}。
c
这是from collections import OrderedDict
total = 18
def main():
custom_print(calc_magic_2d_list(total))
def calc_magic_2d_list(tot):
def check_magic(arr):
if not len(arr) == 9:
return False
for no in arr:
if no <= 0 or not (no - int(no)) == 0:
return False
return True
x5 = tot / 3
if x5 > 0 and (x5 - int(x5)) == 0:
pass
else:
raise Exception('no magic boxes of 9 cells for total of {}'.format(str(tot)))
magic_boxes = set()
for y9 in range(tot):
for y8 in range(tot):
magic_box = []
magic_box.append(2*tot/3 - y9)
magic_box.append(2*tot/3 - y8)
magic_box.append((-tot)/3 + y8 + y9)
magic_box.append((-2*tot)/3 + y8 + 2*y9)
magic_box.append(tot/3)
magic_box.append(4*tot/3 - y8 - 2*y9)
magic_box.append(tot - y8 - y9)
magic_box.append(y8)
magic_box.append(y9)
magic_box = OrderedDict.fromkeys(magic_box)
if check_magic(magic_box):
magic_box = [int(x) for x in magic_box]
magic_boxes.add(tuple(magic_box[:]))
return magic_boxes
def custom_print(lst_of_magic):
for magic in lst_of_magic:
print(magic)
if __name__ == '__main__':
main()
时的输出:
c = 18