Magic squares of odd order: Difference between revisions

m (→‎{{header|Phix}}: added syntax colouring, marked p2js compatible)
Line 3,253:
{42,29,23,17,11, 5,48}}
</pre>
 
=={{header|Picat}}==
{{Trans|J}}
 
<lang Picat>import util.
 
go =>
foreach(N in [3,5,17])
M=magic_square(N),
print_matrix(M),
check(M),
nl
end,
nl.
 
%
% Not as nice as the J solution.
% But I like the chaining of the functions.
%
magic_square(N) = MS =>
if N mod 2 = 0 then
printf("N (%d) is not odd!\n", N),
halt
end,
R = make_rotate_list(N), % the rotate indices
MS = make_square(N).transpose().rotate_matrix(R).transpose().rotate_matrix(R).
 
%
% make a square matrix of size N (containing the numbers 1..N*N)
%
make_square(N) = [[I*N+J : J in 1..N]: I in 0..N-1].
 
%
% rotate list:
% rotate_list(11) = [-5,-4,-3,-2,-1,0,1,2,3,4,5]
%
make_rotate_list(N) = [I - ceiling(N / 2) : I in 1..N].
 
%
% rotate the matrix M according to rotate list R
%
rotate_matrix(M, R) = [rotate_n(Row,N) : {Row,N} in zip(M,R)].
 
%
% Rotate the list L N steps (either positive or negative N)
% rotate(1..10,3) -> [4,5,6,7,8,9,10,1,2,3]
% rotate(1..10,-3) -> [8,9,10,1,2,3,4,5,6,7]
%
rotate_n(L,N) = Rot =>
Len = L.length,
R = cond(N < 0, Len + N, N),
Rot = [L[I] : I in (R+1..Len) ++ 1..R].
 
%
% Check if M is a magic square
%
check(M) =>
N = M.length,
Sum = N*(N*N+1) // 2, % The correct sum.
println(sum=Sum),
Rows = [sum(Row) : Row in M],
Cols = [sum(Col) : Col in M.transpose()],
Diag1 = sum([M[I,I] : I in 1..N]),
Diag2 = sum([M[I,N-I+1] : I in 1..N]),
All = Rows ++ Cols ++ [Diag1, Diag2],
OK = true,
foreach(X in All)
if X != Sum then
printf("%d != %d\n", X, Sum),
OK := false
end
end,
if OK then
println(ok)
else
println(not_ok)
end,
nl.
 
% Print the matrix
print_matrix(M) =>
N = M.len,
printf("N=%d\n",N),
Format = to_fstring("%%%dd",max(flatten(M)).to_string().length+1),
foreach(Row in M)
foreach(X in Row)
printf(Format, X)
end,
nl
end,
nl.</lang>
 
Output:
<pre>N=3
6 7 2
1 5 9
8 3 4
 
sum = 15
ok
 
 
N=5
9 15 16 22 3
20 21 2 8 14
1 7 13 19 25
12 18 24 5 6
23 4 10 11 17
 
sum = 65
ok
 
N=17
27 45 63 81 99 117 135 153 154 172 190 208 226 244 262 280 9
62 80 98 116 134 152 170 171 189 207 225 243 261 279 8 26 44
97 115 133 151 169 187 188 206 224 242 260 278 7 25 43 61 79
132 150 168 186 204 205 223 241 259 277 6 24 42 60 78 96 114
167 185 203 221 222 240 258 276 5 23 41 59 77 95 113 131 149
202 220 238 239 257 275 4 22 40 58 76 94 112 130 148 166 184
237 255 256 274 3 21 39 57 75 93 111 129 147 165 183 201 219
272 273 2 20 38 56 74 92 110 128 146 164 182 200 218 236 254
1 19 37 55 73 91 109 127 145 163 181 199 217 235 253 271 289
36 54 72 90 108 126 144 162 180 198 216 234 252 270 288 17 18
71 89 107 125 143 161 179 197 215 233 251 269 287 16 34 35 53
106 124 142 160 178 196 214 232 250 268 286 15 33 51 52 70 88
141 159 177 195 213 231 249 267 285 14 32 50 68 69 87 105 123
176 194 212 230 248 266 284 13 31 49 67 85 86 104 122 140 158
211 229 247 265 283 12 30 48 66 84 102 103 121 139 157 175 193
246 264 282 11 29 47 65 83 101 119 120 138 156 174 192 210 228
281 10 28 46 64 82 100 118 136 137 155 173 191 209 227 245 263
 
sum = 2465
ok</pre>
 
Testing a larger instance:
<lang Picat>
go2 =>
N = 313,
M = magic_square(N),
check(M),
nl.</lang>
 
Output:
<pre>sum = 15332305
ok</pre>
 
 
=={{header|PicoLisp}}==
495

edits