This simple algorithm can generate a magic square of any odd size. It is interesting that no similarly simple algorithm exists for the even sizes (although algorithms are known for this case, too).

Due to the importance of teaching as many people as possible how to write down a magic square, I present this algorithm in a specific form, for the case n=7; but it really does work for any odd size. (Comments for the general case will appear in parentheses).

First, prepare a 7x7 grid (n x n grid, of course). Write down "1" in the centre of the first row. The rule for writing the next integer is to go in the "northeast" direction, i.e. up and right, from the position of the last number. Immediately when we try to write down "2", we discover that we cannot go up from the first row; just wrap around to the bottom whenever you're at the top row, or to the left whenever you're at the leftmost column. So after writing down the integers 1, ..., 7, the situation looks like this:

            1
         7       
      6  *         
   5           
                     4
                  3  
               2    
Now we're well and truly stuck. This always happens when you write down a number divisible by 7 (n, in the general case). So shift down for the next number (the 8 goes where the "*" is).

After filling in 8, ..., 14, we're again blocked:

             1 10
          7  9    
       6  8         
    5 14          
   13  *              4
                   3 12
                2 11 
so we go down again, and continue in this manner.

At the end, we're left with this:

   30 39 48  1 10 19 28
   38 47  7  9 18 27 29
   46  6  8 17 26 35 37
    5 14 16 25 34 36 45
   13 15 24 33 42 44  4
   21 23 32 41 43  3 12
   22 31 40 49  2 11 20
Note how after writing down "49", 43 blocks our north-eastern move, and 1 blocks our downwards move. More interestingly, perhaps, note that we have our magic square.

This is a program to generate a magic square using the Siamese method
(as described above).
It begins with placeing 1 in any location (in the code it was placed
at the top center).

#!/usr/local/bin/perl5

$n = shift @ARGV;
if(not $n % 2) { die "$n is not odd.\n"; }

$x = int($n/2); $y = 0;

my @S;

for ($i = 1; $i <= ($n * $n); $i++)
{
    if($S[$x][$y] == 0)
      { $S[$x][$y] = $i; }
    else
    { 
        $x ++;
        $x %= $n;
        $y += 2;
        $y %= $n;
        $S[$x][$y] = $i;
    }   
    $x--;
    $x %= $n;
    $y--;
    $y %= $n;
}   
    
for ($y = 0; $y < $n; $y++)
{
    for($x = 0; $x < $n; $x++)
      { print "$S[$x][$y]\t"; }
    print "\n";
}

Log in or register to write something here or to contact authors.