-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathMagic_Square.py
More file actions
131 lines (117 loc) · 4.47 KB
/
Magic_Square.py
File metadata and controls
131 lines (117 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- coding:utf-8 -*-
# &Author AnFany
# 引入库
import numpy as np
# 奇数阶
def OddMagic(jieshu):
# 存储幻方结构
huanfang = np.zeros((jieshu, jieshu))
# 需要填写的数字列表
listnum = list(range(1, jieshu ** 2 + 1))
# 第一行中间填1
i = 0
j = int(jieshu / 2)
# 记录填写的个数
count = 0
while count < jieshu ** 2:
huanfang[i][j] = listnum[count]
# 记录i,j
cc = i
dd = j
# 超出了第一行,则填到最底下一行
if i - 1 < 0:
i = jieshu - 1
else:
i -= 1
# 超出了最右边一列,则填到最左边一列
if j + 1 == jieshu:
j = 0
else:
j += 1
# 遇到下一个格子里已经有数字的,就填到当前格子的下方
if huanfang[i][j] != 0:
i = cc + 1
j = dd
# 次序加1
count += 1
return huanfang
# 双偶阶幻方:阶数=2*偶数
def DoubleEvenMagic(jieshu):
##存储幻方结构
huanfang = np.zeros((jieshu, jieshu))
# 需要填写的数字列表
listnum = list(range(1, jieshu ** 2 + 1))
# 第一轮填充,从第一行第一列开始,从左到右,从上到下,从1到jieshu平方,依次填充
# 每四乘四的正方形,画主副对角线。规则是只填充没对角线的,画了对角线格子不写
# 记录个数
count = 0
for hang in range(len(huanfang)):
for lie in range(len(huanfang)):
if (hang % 4 in [0, 3] and lie % 4 in [1, 2]) or \
(hang % 4 in [1, 2] and lie % 4 in [0, 3]): # 判断对角线
huanfang[hang][lie] = listnum[count]
# 第二轮填充,从最后一行最后一列开始,从右到左,从下到上,从1到jieshu平方依次填充。
# 规则是只填充画了对角线的,没画对角线的不填
else:
huanfang[hang][lie] = listnum[::-1][count]
count += 1
return huanfang
# 单偶阶幻方:阶数=2*奇数
def SingleEvenMagic(jieshu):
# 幻方结构
huanfang = np.zeros((jieshu, jieshu))
# 子幻方阶数
son = int(jieshu / 2)
# A象限幻方
SAhf = OddMagic(son)
huanfang[:, 0:son][0:son] = SAhf
# 依次填充DBC象限
huanfang[:, son:][son:] = huanfang[:, 0:son][0:son] + son ** 2
huanfang[:, son:][0:son] = huanfang[:, son:][son:] + son ** 2
huanfang[:, 0:son][son:] = huanfang[:, son:][0:son] + son ** 2
# 计算K值
k = int((jieshu - 2) / 4)
# AC象限互换
# 从A象限的中间行中间列开始为第一格,往右标出K格;标出A象限其他行的左边K列
# 先换AC象限所有行的左边K列
middle = huanfang[:, 0:k][0:son].copy()
huanfang[:, 0:k][0:son] = huanfang[:, 0:k][son:]
huanfang[:, 0:k][son:] = middle
# 再换中间行的前2K列
middle = huanfang[:, 0:2 * k][int(son / 2):(int(son / 2) + 1)].copy()
huanfang[:, 0:2 * k][int(son / 2):(int(son / 2) + 1)] = huanfang[:, 0:2 * k][
int(son / 2) + son:(int(son / 2) + 1 + son)]
huanfang[:, 0:2 * k][int(son / 2) + son:(int(son / 2) + 1 + son)] = middle
# BD象限互换
if k - 1 != 0:
# 从B象限的中间列所有格子开始,向左标出K-1列,与D象限对换
middle = huanfang[:, son:son + k - 1][0:son].copy()
huanfang[:, son:son + k - 1][0:son] = huanfang[:, son:son + k - 1][son:]
huanfang[:, son:son + k - 1][son:] = middle
return huanfang
# 最终构建幻方的函数
def Magic(jieshu):
if jieshu < 3:
return '阶数不应小于3'
elif jieshu % 2 == 1:
huanfang = OddMagic(jieshu)
elif jieshu % 4 != 0:
huanfang = SingleEvenMagic(jieshu)
else:
huanfang = DoubleEvenMagic(jieshu)
return huanfang
# 验证幻方的函数
def Test(jieshu):
cc = Magic(jieshu)
sumlist = list(cc.sum(axis=1)) + list(cc.sum(axis=0)) + [cc.trace()] # 所有行、列以及主对角线数字和
vicediag = 0
for iv in range(jieshu):
vicediag += cc[iv][jieshu - iv - 1]
sumlist += [vicediag] # 加上副对角线数字和
if len(set(sumlist)) == 1: # 判断和相等
print(cc)
return '结果正确'
else:
print('%s阶程序有bug' % jieshu)
return False
print(Test(7))