Click here to Skip to main content
15,881,248 members
Articles / Programming Languages / C++
Article

Magic Square

Rate me:
Please Sign up or sign in to vote.
4.67/5 (45 votes)
8 Sep 20032 min read 407.6K   3.9K   38   44
Calculating Magic Square In Any Order Using Standard Template Library (STL)

Sample Image - Magic_Square.jpg

Introduction

Magic square is an ancient mathematical problem that many people try to solve. May be you see it in some magazines or your teacher might have introduced it in a class.

Details

A magic square is an arrangement of numbers from 1 to n2 in an [n x n] matrix, with each number occurring exactly once, and such that the sum of the entries of any row, any column, or any main diagonal is the same.

It is not hard to show that this sum must be  n [ ( n2 + 1) / 2 ]. If we use this formula for that example output which is below, for [5x5] matrix; 5 [ ( 52 + 1 ) / 2 ] = 65.

1724181565
2357141665
4613202265
10121921365
1118252965
656565656565

Now, I want to show you a way to calculating magic squares in any order by using your talented computer.

Siamese method

This method is useful for calculating magic squares with odd order. It begins by placing a 1 in any location (in the center square of the top row in the above example), then incrementally placing subsequent numbers in the square one unit above and to the right. The counting is wrapped around, so that falling off the top returns on the bottom and falling off the right returns on the left. When a square is encountered which is already filled, the next number is instead placed below the previous one and the method continues as before. The method, also called de la Loubere's method.

For example, if order of square is 5, we have:

void CalculateOddMagicSquare()
{
  n=5;
  int matrix[5][5];

  int nsqr = n * n;
  int i=0, j=n/2;     // start position

  for (int k=1; k<=nsqr; ++k) 
  {
    matrix[i][j] = k;

    i--;
    j++;

    if (k%n == 0) 
    { 
      i += 2; 
      --j; 
    }
    else 
    {
      if (j==n) 
        j -= n;
      else if (i<0) 
        i += n;
    }
  }
}

Here is a very nice flash animation to show you how to fill square's cells. Thanks KIVANÇ HiKMET ANAR, for his flash.

Complete Work

Below is full source code of calculating magic squares in any order.

#include "stdafx.h"
#include <vector>

using namespace std;

void OddMagicSquare(vector<vector<int> > &matrix, int n);
void DoublyEvenMagicSquare(vector<vector<int> > &matrix, int n);
void SinglyEvenMagicSquare(vector<vector<int> > &matrix, int n);
void MagicSquare(vector<vector<int> > &matrix, int n);
void PrintMagicSquare(vector<vector<int> > &matrix, int n);

int main(int argc, char* argv[])
{
  int n;
  printf("Enter order of square: ");
  scanf("%d", &n);

  vector<vector<int> > matrix(n, vector<int> (n, 0));

  if (n<3)
  {
    printf("\nError: n must be greater than 2\n\n");
    return -1;
  }

  MagicSquare(matrix, n);  

  //Print results
  PrintMagicSquare(matrix, n);
    
  return 0;
}

void MagicSquare(vector<vector<int> > &matrix,int n)
{
  if (n%2==1)        //n is Odd
    OddMagicSquare(matrix, n);
  else          //n is even
    if (n%4==0)    //doubly even order
      DoublyEvenMagicSquare(matrix, n);
    else      //singly even order
      SinglyEvenMagicSquare(matrix, n);
}

void OddMagicSquare(vector<vector<int> > &matrix, int n)
{
  int nsqr = n * n;
  int i=0, j=n/2;     // start position

  for (int k=1; k<=nsqr; ++k) 
  {
    matrix[i][j] = k;

    i--;
    j++;

    if (k%n == 0) 
    { 
      i += 2; 
      --j; 
    }
    else 
    {
      if (j==n) 
        j -= n;
      else if (i<0) 
        i += n;
    }
  }
}

void DoublyEvenMagicSquare(vector<vector<int> > &matrix, int n)
{
  vector<vector<int> > I(n, vector<int> (n, 0));
  vector<vector<int> > J(n, vector<int> (n, 0));

  int i, j;

  //prepare I, J
  int index=1;
  for (i=0; i<n; i++)
    for (j=0; j<n; j++)
    {
      I[i][j]=((i+1)%4)/2;
      J[j][i]=((i+1)%4)/2;
      matrix[i][j]=index;
      index++;
    }

  for (i=0; i<n; i++)
    for (j=0; j<n; j++)
    {
      if (I[i][j]==J[i][j])
        matrix[i][j]=n*n+1-matrix[i][j];
    }
}

void SinglyEvenMagicSquare(vector<vector<int> > &matrix, int n)
{
  int p=n/2;

  vector<vector<int> > M(p, vector<int> (p, 0));
  MagicSquare(M, p);
  
  int i, j, k;

  for (i=0; i<p; i++)
    for (j=0; j<p; j++)
    {
      matrix[i][j]=M[i][j];
      matrix[i+p][j]=M[i][j]+3*p*p;
      matrix[i][j+p]=M[i][j]+2*p*p;
      matrix[i+p][j+p]=M[i][j]+p*p;
    }

  if (n==2)
    return;  

  vector<int> I(p, 0);
  vector<int> J;

  for (i=0; i<p; i++)
    I[i]=i+1;

  k=(n-2)/4;
  
  for (i=1; i<=k; i++)
    J.push_back(i);

  for (i=n-k+2; i<=n; i++)
    J.push_back(i);

  int temp;
  for (i=1; i<=p; i++)
    for (j=1; j<=J.size(); j++)
    {
      temp=matrix[i-1][J[j-1]-1];
      matrix[i-1][J[j-1]-1]=matrix[i+p-1][J[j-1]-1];
      matrix[i+p-1][J[j-1]-1]=temp;
    }

  //j=1, i
  //i=k+1, k+1+p
  i=k; 
  j=0;
  temp=matrix[i][j]; matrix[i][j]=matrix[i+p][j]; matrix[i+p][j]=temp;

  j=i;
  temp=matrix[i+p][j]; matrix[i+p][j]=matrix[i][j]; matrix[i][j]=temp;
}


void PrintMagicSquare(vector<vector<int> > &matrix, int n)
{
  for (int i=0; i<n; i++) 
  {
    for (int j=0; j<n; j++)
      printf(" %3d", matrix[i][j]);

    printf("\n");
  }

  printf("\n\n");
}

Conclusion

Enjoy!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
CEO Solaris Electronics LLC
United Arab Emirates United Arab Emirates
I was born in Shiraz, a very beautiful famous city in Iran. I started programming when I was 12 years old with GWBASIC. Since now, I worked with various programming languages from Basic, Foxpro, C/C++, Visual Basic, Pascal to MATLAB and now Visual C++.
I graduated from Iran University of Science & Technology in Communication Eng., and now work as a system programmer for a telecommunication industry.
I wrote several programs and drivers for Synthesizers, Power Amplifiers, GPIB, GPS devices, Radio cards, Data Acquisition cards and so many related devices.
I'm author of several books like Learning C (primary and advanced), Learning Visual Basic, API application for VB, Teach Yourself Object Oriented Programming (OOP) and etc.
I'm winner of January, May, August 2003 and April 2005 best article of month competition, my articles are:


You can see list of my articles, by clicking here


Comments and Discussions

 
QuestionImprovemment : Random Odd Magic square code Pin
theMadCoder4-Sep-19 5:33
theMadCoder4-Sep-19 5:33 
QuestionImprovement over Magic square Pin
Kannadakanda26-Jun-19 4:26
Kannadakanda26-Jun-19 4:26 
QuestionWhat's wrong with my Magic Square program? Pin
Trevon Harris21-Feb-15 20:25
Trevon Harris21-Feb-15 20:25 
Generalthank you...... Pin
aravindanne24-Jan-12 5:24
aravindanne24-Jan-12 5:24 
Questiona more general algorithm for generating magic squares Pin
ashishkumar3666-Nov-11 12:15
ashishkumar3666-Nov-11 12:15 
Questionprogram of magic square Pin
Member 820125830-Aug-11 15:58
Member 820125830-Aug-11 15:58 
Questionmagic square program Pin
sheila mejos30-Aug-11 15:09
sheila mejos30-Aug-11 15:09 
Questiondomino problem Pin
SOLR@C21-May-11 15:59
SOLR@C21-May-11 15:59 
Generalhelp me Pin
mashmal11-Apr-11 11:47
mashmal11-Apr-11 11:47 
Generalhelp me please to expand my knowledge in programming.. Pin
nycshoes0317-Jul-09 17:12
nycshoes0317-Jul-09 17:12 
#include<stdio.h>
#define row 5
#define column

int main(void)
{
int n,i,j,k,I,J;
int table[5][5];
{
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{
if (I[i][j]==J[i][j])
matrix[i][j]=n*n+1-matrix[i][j];
}
}
}
void CalculateOddMagicSquare()
{
int 5;
int matrix[5][5];

int nsqr = n * n;
int i=0, j=n/2;

for (int k=1; k<=nsqr; ++k)
{
matrix[i][j] = k;

i--;
j++;

if (k%n == 0)
{
i += 2;
--j;
}
else
{
if (j==n)
j -= n;
else if (i<0)
i += n;
}
}
}
void PrintMagicSquare([5][5])
{
for (int i=0; i<n; i++)
{
for (int j=0; j<n; j++)
printf(" %3d", matrix[i][j]);

printf("\n");
}

printf("\n\n");
}
That the program correct?that can output the correct 5x5 magic square?
help me please constructing an n x n magic square for any odd integer n. Place 1 in the middle of the top row. Then after integer k has been placed, move up one row and one column to the right to place the next integer k + 1, unless one of the following occurs:

• If a move takes you above the top row in the jth column, move to the bottom of the jth column and place k + 1 there.
• If a move takes you outside to the right of the square in the ith row, place k + 1 in the ith row at the left side.
• If a move takes you to an already filled square or if you move out of the square at the upper right-hand corner, place k + 1 immediately below k.

TEACH ME 2 HOW CONSTRUCT 5X5 MAGIC SQUARE..THANKS A LOT AND MORE POWER..

IM NEEDING UR REPLY..
Generalmagic square Pin
samantha0315-Jul-09 19:56
samantha0315-Jul-09 19:56 
Questionhelp me plzz Pin
dongky19864-Feb-09 1:41
dongky19864-Feb-09 1:41 
Questionproblem Pin
Member 47188233-Sep-08 8:54
Member 47188233-Sep-08 8:54 
GeneralHelp_Magic Square Pin
00713-Jan-08 4:45
00713-Jan-08 4:45 
QuestionCan anyone help with this program [modified] Pin
Well Alright 200411-Jun-07 14:14
Well Alright 200411-Jun-07 14:14 
QuestionSolvin a Magic Saquare in other method Pin
Nizar Hawat6-Jan-07 11:45
Nizar Hawat6-Jan-07 11:45 
GeneralHeLP me to solve this probLem, pLease! Pin
winche9-May-06 2:12
winche9-May-06 2:12 
Generalhelp Pin
Shay00730-Mar-06 19:55
Shay00730-Mar-06 19:55 
GeneralMagic Square Flaw Pin
bugDanny26-Sep-05 3:56
bugDanny26-Sep-05 3:56 
GeneralRe: Magic Square Flaw Pin
Abbas_Riazi26-Sep-05 4:10
professionalAbbas_Riazi26-Sep-05 4:10 
GeneralRe: Magic Square Flaw Pin
bugDanny26-Sep-05 4:18
bugDanny26-Sep-05 4:18 
Generalhi prof Pin
Anonymous24-Sep-05 17:24
Anonymous24-Sep-05 17:24 
GeneralComplete Distributed Solution Pin
MagicSquareJoe22-Jul-04 17:22
MagicSquareJoe22-Jul-04 17:22 
GeneralYour Complete Work Pin
Anonymous15-Nov-03 14:55
Anonymous15-Nov-03 14:55 
GeneralRe: Your Complete Work Pin
Anthony_Yio21-Dec-03 21:32
Anthony_Yio21-Dec-03 21:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.