Click here to Skip to main content
6,822,613 members and growing! (19,732 online)
Email Password   helpLost your password?
General Programming » Algorithms & Recipes » Algorithms     Intermediate

Magic Square

By A. Riazi

Calculating Magic Square In Any Order Using Standard Template Library (STL)
VC6Win2K, WinXP, Win2003, STL, Dev
Posted:8 Sep 2003
Views:141,791
Bookmarked:27 times
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
32 votes for this article.
Popularity: 6.40 Rating: 4.26 out of 5
4 votes, 12.5%
1
1 vote, 3.1%
2
4 votes, 12.5%
3
4 votes, 12.5%
4
19 votes, 59.4%
5

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.

17 24 1 8 15 65
23 5 7 14 16 65
4 6 13 20 22 65
10 12 19 21 3 65
11 18 25 2 9 65
65 65 65 65 65 65

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

About the Author

A. Riazi


Member
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 Acqusition 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 competetion, my articles are:


You can see list of my articles, by clicking here


Occupation: Software Developer (Senior)
Company: Misbah3Com
Location: Iran (Islamic Republic Of) Iran (Islamic Republic Of)

Other popular Algorithms & Recipes articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 35 (Total in Forum: 35) (Refresh)FirstPrevNext
Generalhelp me please to expand my knowledge in programming.. Pinmembernycshoes0318:12 17 Jul '09  
Generalmagic square Pinmembersamantha0320:56 15 Jul '09  
Questionhelp me plzz Pinmemberdongky19862:41 4 Feb '09  
Questionproblem PinmemberMember 47188239:54 3 Sep '08  
GeneralHelp_Magic Square Pinmember0075:45 13 Jan '08  
QuestionCan anyone help with this program [modified] PinmemberWell Alright 200415:14 11 Jun '07  
QuestionSolvin a Magic Saquare in other method PinmemberNizar Hawat12:45 6 Jan '07  
GeneralHeLP me to solve this probLem, pLease! Pinmemberwinche3:12 9 May '06  
Generalhelp PinmemberShay00720:55 30 Mar '06  
GeneralMagic Square Flaw PinmemberbugDanny4:56 26 Sep '05  
GeneralRe: Magic Square Flaw PinmemberA. Riazi5:10 26 Sep '05  
GeneralRe: Magic Square Flaw PinmemberbugDanny5:18 26 Sep '05  
Generalhi prof PinsussAnonymous18:24 24 Sep '05  
GeneralComplete Distributed Solution PinmemberMagicSquareJoe18:22 22 Jul '04  
GeneralYour Complete Work PinsussAnonymous15:55 15 Nov '03  
GeneralRe: Your Complete Work PinmemberAnthony_Yio22:32 21 Dec '03  
GeneralRe: Your Complete Work PinmemberGiles3:53 13 Sep '04  
GeneralRe: Your Complete Work PinsussAnonymous15:49 18 Sep '04  
GeneralCould you explain this line? PinmemberWREY14:33 10 Sep '03  
GeneralRe: Could you explain this line? PinsussAnonymously16:43 10 Sep '03  
GeneralRe: Could you explain this line? PinmemberJohn A. Johnson21:36 10 Sep '03  
GeneralRe: Could you explain this line? PinmemberWREY23:46 10 Sep '03  
GeneralRe: Could you explain this line? PinmemberA. Riazi1:03 11 Sep '03  
GeneralRe: Could you explain this line? PinmemberJohn A. Johnson3:48 11 Sep '03  
GeneralRe: Could you explain this line? PinmemberA. Riazi5:38 11 Sep '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

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

PermaLink | Privacy | Terms of Use
Last Updated: 8 Sep 2003
Editor: Nishant Sivakumar
Copyright 2003 by A. Riazi
Everything else Copyright © CodeProject, 1999-2010
Web21 | Advertise on the Code Project