1 ## Copyright (C) 1999-2012 Paul Kienzle
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {} magic (@var{n})
22 ## Create an @var{n}-by-@var{n} magic square. A magic square is an arrangement
23 ## of the integers @code{1:n^2} such that the row sums, column sums, and
24 ## diagonal sums are all equal to the same value.
26 ## Note: @var{n} must be greater than 2 for the magic square to exist.
35 if (n != fix (n) || n < 0 || n == 2)
36 error ("magic: N must be a positive integer not equal to 2");
43 elseif (mod (n, 2) == 1)
45 shift = floor ((0:n*n-1)/n);
46 c = mod ([1:n*n] - shift + (n-3)/2, n);
47 r = mod ([n*n:-1:1] + 2*shift, n);
49 A = reshape (A, n, n);
51 elseif (mod (n, 4) == 0)
53 A = reshape (1:n*n, n, n)';
61 elseif (mod (n, 4) == 2)
65 A = [A, A+2*m*m; A+3*m*m, A+m*m];
70 A([I,I+m],J) = A([I+m,I],J);
73 A([I,I+m],1) = A([I+m,I],1);
75 A([I,I+m],I) = A([I+m,I],I);
85 %! assert (norm(diff([sum(diag(A)),sum(diag(flipud(A))),sum(A),sum(A')])),0);
88 %!assert (isempty (magic (0)))
89 %!assert (magic(1), 1)
91 %% Test input validation
94 %!error <N must be a positive integer not equal to 2> magic (1.5)
95 %!error <N must be a positive integer not equal to 2> magic (-1)
96 %!error <N must be a positive integer not equal to 2> magic (2)