# What programming language would be complete without magic squares?

# This function generates magic squares.  A magic square is a square
# matrix of order N whose elements consist of the consecutive whole
# numbers from 1 to N^2, arranged so that the sums of each row, each
# column, and each diagonal are all equal.

# Note that magic(2) is undefined and returns NULL.

# This code is taken from Octave (http://www.octave.org/), replacing
# Algae's original implementation because it's faster.  For sentimental
# reasons, the original is included as comments at the bottom.

magic = function (n)
{
  local (shift; c; r; A; I; J; m; n2; k; n2s; m2);

  n = scalar (integer (n));
  n2 = n^2;

  if (n == 1)
  {
    return [1];

  elseif (n < 3)

    return NULL;

  elseif (n % 2)

    n2s = 1:n2;
    shift = floor ((n2s-1)/n);
    c = (n2s - shift + (n-3)/2) % n;
    r = ((n2:1) + 2*shift) % n;
    A = fill (n2; 0);
    A [c*n+r+1] = n2s;
    A = fill (n,n; A);

  elseif (n % 4)

    m = n/2;
    m2 = m^2;
    A = magic (m);
    A = [A, A+2*m2; A+3*m2, A+m2 ];
    k = (m-1)/2;
    if (k > 1)
    {
      I = 1:m;
      J = 2:k, n-k+2:n;
      A [I,I+m; J] = A [I+m,I; J];
    }
    I = 1:k, k+2:m;
    A [I,I+m; 1] = A [I+m,I; 1];
    I = k + 1;
    A [I,I+m; I] = A [I+m,I; I];

  else

    A = fill (n,n; 1:n2);
    I = 1:n:4, 4:n:4; J = I[;I.ne:1];
    A [I;I] = A [J;J];
    I = 2:n:4, 3:n:4; J = I[;I.ne:1];
    A [I;I] = A [J;J];

  }

  return A;
};

# # I hacked this up one night when I should have been working on the
# # house.  (That's my excuse for this mess.)
# 
# # Copyright (C) 1994-96  K. Scott Hunziker.
# 
# magic = function (n)
# {
#   local (x; i; j; r; c; v);
# 
#   n = scalar (integer (n));
# 
#   if (n == 1) { return [1]; }
#   if (n < 3) { return NULL; }
# 
#   if (n % 2)
#   {
#     x = fill (n,n; 0);
#     for (i in 1:n)
#     {
#       v = (i-1)*n + 1 : i*n;
#       r = 2*i-1:2*i-n; r -= n*(r>n); r += n*(r<1);
#       c = (n+3)/2-i:(n+3)/2-i+n-1; c -= n*(c>n); c+= n*(c<1);
#       for (j in 1:n) { x[r[j];c[j]] = v[j]; }
#     }
# 
#   elseif (n % 4)
# 
#     x = self (n/2);
#     x = [ x, x+n^2/2; x+n^2*3/4, x+n^2/4 ];
# 
#     for (i in 1:(n/2-1)/2)
#     {
#         c=x[1:n/2;i];
#         x[1:n/2;i] = x[n/2+1:n;i];
#         x[n/2+1:n;i] = c;
#     }
# 
#     if (n > 6)
#     {
#       for (i in 1:(n/2-1)/2-1)
#       {
#         j = n-i+1;
#         c = x[1:n/2;j];
#         x[1:n/2;j] = x[n/2+1:n;j];
#         x[n/2+1:n;j] = c;
#       }
#     }
# 
#     j = (n+2)/4;
# 
#     c = x[j;1];
#     x[j;1] = x[j+n/2;1];
#     x[j+n/2;1] = c;
# 
#     c = x[j;j];
#     x[j;j] = x[j+n/2;j];
#     x[j+n/2;j] = c;
# 
#   else
# 
#     x = ( self.block (n; 1) [2,1;n:1] +
#           self.block (n; n^2-n+1) [;n:1] );
# 
#     for (i in 2:n/2)
#     {
#       if (i%4 > 1)
#       {
#         r = (self.block (n; (i-1)*n+1) +
#              self.block (n; n^2-i*n+1) [2,1;]);
#       else
#         r = (self.block (n; (i-1)*n+1) [2,1;n:1] +
#              self.block( n; n^2-i*n+1) [;n:1]);
#       }
#       x = [ r[1;]; x; r[2;] ];
#     }
#   }
# 
#   return x;
# };
# 
# magic.block = function (n; s)
# {
#   local (i; j; x)
# 
#   x = fill (2,n; 0);
#   x[2;1] = s;
#   s += 1;
#   i = 1;
# 
#   for (j in n-1:2:2)
#   {
#     if (i == 1)
#     {
#       x[1;j] = s;
#       x[1;j-1] = s+1;
#       i=2;
#     else
#       x[2;j-1] = s;
#       x[2;j] = s+1;
#       i=1;
#     }
#     s += 2;
#   }
#   x[2;n] = s;
# 
#   return x;
# };
# 
# magic.check = function (x)
# {
#   local (ones; sum; i);
# 
#   ones = (1:x.nr)*0+1;
#   sum = 0;
#   for (i in 1:x.nr) { sum += x[i;i]; }
#   return (!test (diag(x)*ones != sum) &
#           !test (x*ones != sum) &
#           !test (ones*x != sum));
# };


syntax highlighted by Code2HTML, v. 0.9.1