The 3 x 3 Magic Square to the left is the "basic" 3 x 3 Magic Square. It uses the numbers 1 to
9 inclusive, and its "Magic Total" is **15**, as predicted by the formula shown on
another page.

There is an **excellent** discussion of how to construct a 3 x 3 Magic Square by logical
deduction alone in
"*In Code*" by Sarah & David Flannery.

Various mathematicians (e.g. Cornelius Agrippa, Poignard, Ozanam, Bachet de Mézeriac, Devedec, Philippe De La Hire, Professor Scheffler, Benjamin Franklin) throughout the years have devised methods of creating Magic Squares, but the simplest rules for forming such a "basic" Magic Square, sometimes called the "staircase" method and devised by De La Loubère in the late seventeenth century, are as follows: |

- Write the number 1 in the centre cell on the top row.
- Move one cell up and one cell to the right. (To do this, you have to assume that the top row "wraps round" to the bottom row, and the right column "wraps round" to the left column.)
- If this cell is empty, write in the next highest number in the sequence.
- If this cell is not empty, move down one cell, within the same column, "wrapping round" from the bottom row to the top row if necessary.
- Repeat steps 2 to 4 until all cells have been completed. The largest number in the sequence should be in the middle of the bottom row; if this is not the case, then you have probably made a mistake somewhere.

My fascination with this generic method and its application to "odd" Magic Squares of any order, even large ones, led me to create the following computer program. This program will create a "basic", "odd" Magic Square for any order, and it will run quite easily on most home or business computers, provided that a version of BASIC (Beginners' All Purpose Symbolic Instruction Code) is available. The only limitations are those of computer memory and/or paper size (if the Magic Square is to be printed)!

10 | INPUT X | |

20 | IF (X<3) OR (INT(X/2)=X/2) THEN 10 | |

30 | DIM N(X*X) | |

40 | FOR A=1 TO (X*X) | |

50 | N(A)=0 | |

60 | NEXT A | |

70 | Z=((X+1)/2)+(X-1) | |

80 | FOR Y=1 TO (X*X) | |

90 | Z1=Z-(INT(Z/X)*X) | |

100 | IF Z1=0 THEN Z1=X | |

110 | Z2=((Z-Z1)/X)+1 | |

120 | IF Z1=X THEN Z3=1 ELSE Z3=Z1+1 | |

130 | IF Z2=1 THEN Z4=X ELSE Z4=Z2-1 | |

140 | Z5=((Z4-1)*X)+Z3 | |

145 | IF Z2=X THEN Z6=1 ELSE Z6=0 | |

150 | IF N(Z5)<>0 THEN Z3=Z1:Z4=(Z2+1)-(Z6*X) | |

160 | Z5=((Z4-1)*X)+Z3 | |

170 | N(Z5)=Y | |

180 | Z=Z5 | |

190 | NEXT Y | |

200 | ||

210 | PRINT "The following magic square adds up to ";((X*X*X)+X)/2 | |

220 | ||

230 | FOR B=1 TO X*X | |

240 | PRINT RIGHT$(" "+STR$(N(B)),5); | |

250 | IF INT(B/X)=B/X THEN PRINT | |

260 | NEXT B |

Here are some notes that explain how the above program works:

Line 10 requests the user to enter a number, which represents the number of cells on each side of the magic square.
Line 20 checks the number that was entered and ensures that it is an odd number that is greater than two; if it fails this check, the program goes back to Line 10 to ask for another number to be entered. Line 30 creates an empty magic square in memory with enough cells for the magic square that has been requested. Lines 40 to 60 ensures that each cell in this empty magic square is set to an initial value of zero. Line 70 calculates the cell that would contain the value zero, if such a value were present in the magic square; this is effectively the cell that would be before the cell that will contain the number one, and is derived as a start point for the following processing. Line 80 is the start of an iterative piece of processing that will derive the value to be inserted in each of the cells of the magic square (i.e. x2 cells). Lines 90 to 160 calculate the cell that will contain the next value, using the formula explained in Chapter 5 of the above booklet. Line 170 inserts the next value into the cell derived in Lines 90 to 160. Line 180 is used to reset the value calculated in Line 70 so that the iterative processing may begin for the next cell and number. Line 190 marks the end of the iterative processing, and will only stop once all x2 cells have been filled with the numbers from one to x2 inclusive, as appropriate. Lines 200 - 220 prints a blank line, followed by a message stating that the magic square adds up to the "Magic Total" that is derived using the formula given above in Chapter 3, followed by another blank line. Lines 230 - 260 loop round the generated magic square, printing "x" values per row, where "x" is the value entered in line 10 representing the number of cells on each side of the magic square. |

One visitor to my website, **George Pritchard**, was so impressed with what he found here that he converted the above BASIC program in C for me - completely unprompted - and has kindly given permission for it to be reproduced here:

/* *********************************************************************** */

/* Reference basic listing found at - */

/* http://www.markfarrar.co.uk/msqodd01.htm */

/* Basic Program by Mark S. Farrar, 1997 */

/* */

/* Code is simple and somewhat elegant - easily converted */

/* to gnu-C source_code: msqr_odd.c */

/* */

/* *********************************************************************** */

#include

int odd_order_square(int);

int main()

{

int x=0;

//Clear screen & prompt user

printf("\e[2J");

printf("\nOrder of Magic Square");

printf("(Mode Screen Limit: 19)");

//only accept odd numbers - 3 or greater

do{ // 2 REM BASIC

printf("\nODD-NUMBER: ");

scanf("%i",&x); // 10 INPUT X

}while ( (x<3) || (x%2 == 0) ); // 20 IF (X<3) OR (INT(X/2)=X/2) THEN 10

odd_order_square(x);

printf("\n\n");

return 0;

}

int odd_order_square(int x)

{

int a=0,b=0,c=0;

int y=0;

int z[6]; // 25 REM z[] usage is z,z1,z2,z3,z4,z5,z6 below

int n[x*x+1]; // 30 DIM N(X*X)

//zero initialize array

for (a=1; a< x*x+1; a=a+1) // 40 FOR A=1 TO (X*X)

n[a]=0; // 50 N(A)=0

// 60 NEXT A

//calculate and fill array

z[0] = (x+1)/2 + (x-1); // 70 Z=((X+1)/2)+(X-1)

for (y=1; y < x*x+1; y=y+1) // 80 FOR Y=1 TO (X*X)

{

z[1]= z[0] - (z[0]/x) * x; // 90 Z1=Z-(INT(Z/X)*X)

if (z[1]==0) z[1]=x; //100 IF Z1=0 THEN Z1=X

z[2]= (z[0]-z[1])/x + 1; //110 Z2=((Z-Z1)/X)+1

if (z[1]==x) z[3]=1;

else z[3]=z[1]+1; //120 IF Z1=X THEN Z3=1 ELSE Z3=Z1+1

if (z[2]==1) z[4]=x;

else z[4]=z[2]-1; //130 IF Z2=1 THEN Z4=X ELSE Z4=Z2-1

z[5]= (z[4]-1)*x + z[3]; //140 Z5=((Z4-1)*X)+Z3

if (z[2]=x) z[6]=1;

else z[6]=0; //145 IF Z2=X THEN Z6=1 ELSE Z6=0

if (n[z[5]] !=0)

{ z[3]=z[1]; //150 IF N(Z5)<>0 THEN Z3=Z1:Z4=(Z2+1)-(Z6*X)

z[4]= (z[2]+1) - z[6]*x;

}

z[5]= (z[4]-1)*x + z[3]; //160 Z5=((Z4-1)*X)+Z3

n[z[5]]=y; //170 N(Z5)=Y

z[0]=z[5]; //180 Z=Z5

} //190 NEXT Y

//200 PRINT

//Use array in displaying the result

printf("\nThe following magic square ");

printf("adds up to %i.\n\n",((x*x*x)+x)/2);

//210 PRINT "The following magic square adds up to ";((X*X*X)+X)/2

//220 PRINT

for (b = 1; b < x*x+1; b = b+1 ) //230 FOR B=1 TO X*X

{

printf(" %5i", n[b]); //240 PRINT RIGHT$(" "+STR$(N(B)),5);

if (b%x == 0) printf("\n"); //250 IF INT(B/X)=B/X THEN PRINT

} //260 NEXT B

return 1;

}

/* Sample Output

Order of Magic Square (Mode Screen Limit: 19)

ODD-NUMBER: 4

ODD-NUMBER: 9

The following magic square adds up to 369.

37 28 19 10 1 73 64 55 46

36 27 18 9 81 72 63 54 45

26 17 8 80 71 62 53 44 35

16 7 79 70 61 52 43 34 25

6 78 69 60 51 42 33 24 15

77 68 59 50 41 32 23 14 5

67 58 49 40 31 22 13 4 76

57 48 39 30 21 12 3 75 66

47 38 29 20 11 2 74 65 56

*/

And another visitor, **leonardo maffi**, has also kindly contributed yet another version of this program, this one written in Python. Here's the code, but you can also download leonardo's program by right-clicking here:

# odd_magic_squares.py, http://www.markfarrar.co.uk/msqodd01.htm

# Mark S. Farrar.

while True:

x = int(raw_input("Give order, odd and >= 3: "))

if x > 2 and x % 2:

break

n = [0] * (x*x+1)

z = ((x+1)/2) + (x-1)

for y in xrange(1, (x*x)+1):

z1 = z - ((z//x)*x)

if z1 == 0:

z1 = x

z2 = ((z-z1)/x) + 1

if z1 == x:

z3 = 1

else:

z3 = z1 + 1

if z2 == 1:

z4 = x

else:

z4 = z2 - 1

z5 = ((z4-1)*x) + z3

if z2 == x:

z6 = 1

else:

z6 = 0

if n[z5] != 0:

z3 = z1

z4 = (z2+1) - (z6*x)

z5 = ((z4-1)*x) + z3

n[z5] = y

z = z5

# Assert correct result

m = [n[1+i:1+i+x] for i in xrange(0,x*x,x)]

assert len( set(sum(row) for row in m)) == 1

assert len( set(sum(row) for row in zip(*m))) == 1

d1 = [m[i][i] for i in xrange(len(m))]

d2 = [m[len(m)-i-1][i] for i in xrange(len(m))]

assert sum(d1) == sum(d2) == sum(m[0])

print "The following magic square adds up to", ((x*x*x)+x)/2, "\n"

for b in xrange(1, x*x+1):

print str(n[b]).rjust(5),

if not (b % x):

Click on this house to return to my Home Page or on this icon to return to the main Magic Squares page.

Created: Sunday 31st October, 1999

Contact Me

The owner of this website, Mark Farrar, is a participant in the Amazon EU Associates Programme, an affiliate advertising programme designed to provide a means for sites to earn advertising fees by advertising and linking MarkFarrar.co.uk to Amazon properties including, but not limited to, Amazon.co.uk, Javari.co.uk, Amazon.de, Javari.de, Amazon.fr, Javari.fr, Amazon.it and/or Amazon.es.