搜索魔术方块

时间:2019-08-11 03:01:25

标签: python math

我正在尝试创建一个搜索魔术方块的程序。

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

2 个答案:

答案 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评论的 不同的数字 功能。

这些将是方程组和描述它的矩阵:

enter image description here enter image description here

现在,使用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}的x91单元格的替换}。

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