幻方,也称九宫格,宋代数学家杨辉称之为纵横图,是我国一种传统数字游戏。幻方是将从1到若干个数的自然数排成纵横各为若干个数的正方形,使在同一行、同一列和同一对角线上的几个数的和都相等。古时候幻方经常在官府、学堂等场所出见,后来通过印度、阿拉伯等地传到西方,因其奇幻的特性,被称为Magic Square,即“幻方”或“魔方”。
用数学语言表述,幻方是指在n×n(n行n列)的方格里,既不重复又不遗漏地填上n个连续的自然数,每个数占一格,并使排在任一行、任一列和两条对角线上的几个自然数的和都相等,这个和叫幻和,n叫幻方的阶,这样的数表叫n阶幻方。
python求奇数阶幻方
def generate_magic_square(n):
magic_square = [[0] * n for _ in range(n)]
i, j = 0, n // 2
for num in range(1, n**2 + 1):
magic_square[i][j] = num
i -= 1
j += 1
if num % n == 0:
i += 2
j -= 1
elif i < 0:
i = n - 1
elif j == n:
j = 0
return magic_square
n = 3
magic_square = generate_magic_square(n)
for row in magic_square:
print(row)
[8, 1, 6]
[3, 5, 7]
[4, 9, 2]
python求所有幻方
#利用numpy模块构造幻方
import numpy as np
#列表循环向左移offset位
def shift_left(lst, offset):
return [lst[(i+offset)%len(lst)] for i in range(len(lst))]
#列表循环向右移offset位
def shift_right(lst, offset):
return [lst[i-offset] for i in range(len(lst))]
#构造奇数阶幻方函数
def magic_of_odd_order(n):
p = (int)((n-1)/2)
#创建矩阵1
initial_lst1 = list(range(p+1,n))+list(range(p+1))
initial_mat1 = []
for i in range(n):
initial_mat1.append(shift_left(initial_lst1, i))
mat1 = np.array(initial_mat1)
#创建矩阵2
initial_lst2 = list(range(p,-1,-1))+list(range(2*p,p,-1))
initial_mat2 = []
for i in range(n):
initial_mat2.append(shift_right(initial_lst2, i))
mat2 = np.array(initial_mat2)
#创建矩阵3,即元素全为1的矩阵
mat3= np.ones((n,n),dtype=np.int)
#构造幻方
magic = n*mat2+mat1+mat3
return magic
#构造4n阶幻方函数
def magic_of_4n_order(n):
mat = np.array(range(1,n*n+1)).reshape(n,n)
for i in range((int)(n/4)):
for j in range((int)(n/4)):
for k in range(4): #将每个4*4小方块的对角线换成互补元素
mat[k+4*j][k+4*i] = n*n+1-mat[k+4*j][k+4*i]
mat[k+4*j][3-k+4*i] = n*n+1-mat[k+4*j][3-k+4*i]
return mat
#构造4n+2阶幻方函数
def magic_of_4n2_order(n):
p = (int)(n/2)
matA = magic_of_odd_order(p)
matD = matA+p**2
matB = matD+p**2
matC = matB+p**2
#交换矩阵块A与矩阵块C中特定元素的位置
row = (int)((p-1)/2)
for i in range(p):
if i != row:
for k in range((int)((n-2)/4)):
matA[i][k],matC[i][k] = matC[i][k],matA[i][k]
else:
for k in range((int)((n-2)/4)):
matA[i][row+k],matC[i][row+k] = matC[i][row+k],matA[i][row+k]
#交换矩阵块B与矩阵块D中特定元素的位置
col = (int)((p-1)/2)
for j in range(col+2-(int)((n-2)/4),col+1):
for i in range(p):
matB[i][j],matD[i][j] = matD[i][j],matB[i][j]
#合并矩阵块A,B,C,D组成幻方
magic = np.row_stack((np.column_stack((matA,matB)),np.column_stack((matC,matD))))
return magic
def main():
order = eval(input('Enter the order of magic square(>=3): '))
if order%2 ==1:
magic = magic_of_odd_order(order)
elif order%4 == 0:
magic = magic_of_4n_order(order)
else:
magic = magic_of_4n2_order(order)
print('Generating magic square of %d order......'%order)
for row in magic:
for col in row:
print(col, end='\t')
print()
#验证生成的magic是否为幻方
val = input(("Do you want to validate?[Y|N]"))
if val == 'Y' or val == 'y':
print('每行的和:', np.sum(magic, axis=0))
print('每列的和:', np.sum(magic, axis=1))
print('主对角线的和:', sum([magic[i][i] for i in range(order)]))
print('副对角线的和:', sum([magic[i][order-1-i] for i in range(order)]))
print('It\'s Done!')
if __name__ == "__main__":
main()
Enter the order of magic square(>=3): 5
D:\pycharm pjt\1.py:26: DeprecationWarning: `np.int` is a deprecated alias for the builtin `int`. To silence this warning, use `int` by itself. Doing this will not modify any behavior and is safe. When replacing `np.int`, you may wish to use e.g. `np.int64` or `np.int32` to specify the precision. If you wish to review your current use, check the release note link for additional information.
Deprecated in NumPy 1.20; for more details and guidance: https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations
mat3= np.ones((n,n),dtype=np.int)
Generating magic square of 5 order......
14 10 1 22 18
20 11 7 3 24
21 17 13 9 5
2 23 19 15 6
8 4 25 16 12
Do you want to validate?[Y|N]Y
每行的和: [65 65 65 65 65]
每列的和: [65 65 65 65 65]
主对角线的和: 65
副对角线的和: 65
It's Done!