Program To Generate Magic Square Matrix For Any Value Of N

Magic Square Matrix Program

In this article, you’ll learn how to generate a magic square matrix of dimension N x N, for any value of N (any order), be it odd, singly even, or doubly even.

What Is A Magic Square Matrix?

To begin with, let’s first understand the properties of a magic square matrix.

In a magic square matrix, the sums of the elements of each of its columns, rows and diagonals are equal to the same constant, called the magic constant or the magic sum.

Let’s understand this with an example:

Let’s take the magic square matrix of order 3.

Magic Sqaure Matrix 3x3

Sum of its 1st row = 2+7+6 = 15

Sum of its 2nd row = 9+5+1 = 15

Sum of it’s 3rd row = 4+3+8 = 15

Sum of its 1st column = 2+9+4 = 15

Sum of its 2nd column = 7+5+3 = 15

Sum of its 3rd column = 6+1+8 = 15

Sum of its left diagonal = 2+5+8 = 15

Sum of its right diagonal = 6+5+4 = 15

Thus, we can see that the sums of the elements of each of its columns, rows and diagonals are equal to a single constant, that is, 15.

In this case, 15 is the magic constant or the magic sum.

The magic constant value can be obtained by the formula n*(n2+1)/2. Where n is the order of the matrix.

We can cross-check that 3*(32+1)/2 = 3*(10)/2 = 30/2 = 15 is equal to the magic constant.

Program To Generate A Magic Square Matrix Of Any Order

The logic behind generating the magic square matrix varies a little depending on whether the order of the matrix, i.e. the value of n is odd, singly even (divisible by 2), or doubly even (divisible by 4).

The algorithm and the program given in this article handles all values of n, including odd, singly even, and doubly even, and is thus capable of generating magic square matrix of any order, for all values of n

Java Program To Generate Magic Square Matrix Of Any Order

import java.util.Scanner;
public class MagicSquare {

    public void odd(int[][] magic){

        int N = magic.length;
        int row = N-1;
        int col = N/2;
        magic[row][col] = 1;
        for(int i = 2; i<=N*N; i++){
            if(magic[(row+1)%N][(col+1)%N]== 0){
                row = (row+1)%N;
                col = (col+1)%N;
            }else{
                row = (row-1+N)%N;
            }
            magic[row][col] = i;
        }

    }

    public void doublyEven(int[][] magicsqr){
        int N = magicsqr.length;

        int miniSqrNum = N/4; //size of boxes
        int cnt = 1;          //counter 1 to N*N
        int invCnt = N*N;     //counter N*N to 1
        for(int i=0;i<N;i++){

            for(int j=0;j<N;j++){

                if(j>=miniSqrNum && j<N-miniSqrNum){
                    if(i>=miniSqrNum && i<N-miniSqrNum)
                        magicsqr[i][j] = cnt;    //central box
                    else 
                        magicsqr[i][j] = invCnt; // up & down boxes

                }
                else if(i<miniSqrNum || i>=N-miniSqrNum){
                    magicsqr[i][j]=cnt;             // 4 corners
                }
                else
                    magicsqr[i][j] = invCnt;      // left & right boxes

                cnt++;
                invCnt--;
            }

        }

    }

    public void singlyEven(int[][] magicsqr){

        int N = magicsqr.length;
        int halfN = N/2; //size of ABCD boxes
        int k = (N-2)/4; // to get 'noses' of A & D boxes
        int temp;

        int [] swapCol = new int[N]; // columns which need to swap between C-B & A-D
        int index=0; // index of swapCol

        int [][] miniMagic =  new int [halfN][halfN];
        odd(miniMagic); //creating odd magic square for A box

        //creating 4 magic boxes
        for (int i=0; i<halfN; i++)
            for (int j=0; j<halfN; j++){
                magicsqr[i][j] = miniMagic[i][j];               //A box
                magicsqr[i+halfN][j+halfN] = miniMagic[i][j]+halfN*halfN;   //B box
                magicsqr[i][j+halfN] = miniMagic[i][j]+2*halfN*halfN;       //C box
                magicsqr[i+halfN][j] = miniMagic[i][j]+3*halfN*halfN;       //D box
            }

        for (int i=1; i<=k; i++)
            swapCol[index++] = i;

        for (int i=N-k+2; i<=N; i++)
            swapCol[index++] = i;

        //swaping values between C-B & A-D by known columns
        for (int i=1; i<=halfN; i++)
            for (int j=1; j<=index; j++){
                temp=magicsqr[i-1][swapCol[j-1]-1];
                magicsqr[i-1][swapCol[j-1]-1]=magicsqr[i+halfN-1][swapCol[j-1]-1];
                magicsqr[i+halfN-1][swapCol[j-1]-1]=temp;
            }

        //swaping noses
        temp=magicsqr[k][0]; 
        magicsqr[k][0]=magicsqr[k+halfN][0]; 
        magicsqr[k+halfN][0]=temp;

        temp=magicsqr[k+halfN][k]; 
        magicsqr[k+halfN][k]=magicsqr[k][k]; 
        magicsqr[k][k]=temp;
        //end of swaping

    }

    public void showMagicSqr(int[][] magicsqr){
        int N = magicsqr.length;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) 
                System.out.print(magicsqr [i][j] + " ");

            System.out.println();
        }
    }

    public boolean isMagicSqr(int[][] magicsqr){
        int N = magicsqr.length;
        int magicConst = (N*N*N+N)/2;

        int rowsum = 0;
        int colsum = 0;
        int diag1 = 0;
        int diag2 = 0;
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                rowsum += magicsqr[i][j];
                colsum += magicsqr[j][i];
            }
            diag1 += magicsqr[i][i];
            diag2 += magicsqr[i][N-i-1];
            if(rowsum!=magicConst){ return false; }
            if(colsum!=magicConst){ return false; }
            rowsum=0; colsum=0;
        }
        if(diag1!= magicConst || diag2 != magicConst) 
            return false;

        return true;
    }

    public static void main(String[] args) { 
        System.out.println("N? ");
        int N = new Scanner(System.in).nextInt();
        int[][] matrix = new int[N][N];
        MagicSquare ms = new MagicSquare();

        if(N<=2) throw new RuntimeException("A size of matrix must be bigger than 2");

        if (N % 2==1) 
            ms.odd(matrix); 
        else if(N%4 ==0) 
            ms.doublyEven(matrix);     
        else 
            ms.singlyEven(matrix);

        ms.showMagicSqr(matrix);
        if(ms.isMagicSqr(matrix)) 
            System.out.println("isMagicSquare? - YES"); 
        else  
            System.out.println("isMagicSquare? - NO"); 

    }
}

Python Program To Generate Magic Square Matrix Of Any Order

def generateOddSquare(n):
    magicSquare = [[0]*n for i in range(n)]
    i = n // 2
    j = n - 1
    num = 1
    while num <= (n * n):
        if i == -1 and j == n:
            j = n - 2
            i = 0
        else:
            if j == n:
                j = 0
            if i < 0:
                i = n - 1

        if magicSquare[int(i)][int(j)]:
            j = j - 2
            i = i + 1
            continue
        else:
            magicSquare[int(i)][int(j)] = num
            num = num + 1

        j = j + 1
        i = i - 1

    for i in range(0, n):
        for j in range(0, n):
            print(magicSquare[i][j], end=' ')
        print()


def generateDoublyEvenSquare(n):
    arr = [[(n*y)+x+1 for x in range(n)]for y in range(n)]

    for i in range(0, n//4):
        for j in range(0, n//4):
            arr[i][j] = (n*n + 1) - arr[i][j]

    for i in range(0, n//4):
        for j in range(3 * (n//4), n):
            arr[i][j] = (n*n + 1) - arr[i][j]

    for i in range(3 * (n//4), n):
        for j in range(0, n//4):
            arr[i][j] = (n*n + 1) - arr[i][j]

    for i in range(3 * (n//4), n):
        for j in range(3 * (n//4), n):
            arr[i][j] = (n*n + 1) - arr[i][j]

    for i in range(n//4, 3 * (n//4)):
        for j in range(n//4, 3 * (n//4)):
            arr[i][j] = (n*n + 1) - arr[i][j]

    for i in range(n):
        for j in range(n):
            print('%2d ' % (arr[i][j]), end=" ")
        print()


def generateSinglyEvenSquare(n):
    magicsqr = [[0]*n for i in range(n)]
    halfN = n // 2
    k = (n-2)//4
    temp = 0
    swapCol = []
    index = 0
    miniMagic = [[0]*halfN for i in range(halfN)]
    miniMagic = odd(miniMagic)

    for i in range(halfN):
        for j in range(halfN):
            magicsqr[i][j] = miniMagic[i][j]
            magicsqr[i+halfN][j+halfN] = miniMagic[i][j] + halfN*halfN
            magicsqr[i][j+halfN] = miniMagic[i][j] + 2*halfN*halfN
            magicsqr[i+halfN][j] = miniMagic[i][j] + 3*halfN*halfN

    for i in range(1, k+1):
        swapCol.append(i)

    for i in range(n-k+2, n+1):
        swapCol.append(i)

    for i in range(1, halfN+1):
        for j in range(1, len(swapCol)+1):
            temp = magicsqr[i-1][swapCol[j-1]-1]
            magicsqr[i-1][swapCol[j-1]-1] = magicsqr[i+halfN-1][swapCol[j-1]-1]
            magicsqr[i+halfN-1][swapCol[j-1]-1] = temp

    temp = magicsqr[k][0]
    magicsqr[k][0] = magicsqr[k+halfN][0]
    magicsqr[k+halfN][0] = temp

    temp = magicsqr[k+halfN][k]
    magicsqr[k+halfN][k] = magicsqr[k][k]
    magicsqr[k][k] = temp

    for i in range(len(magicsqr)):
        for j in range(len(magicsqr[0])):
            print(magicsqr[i][j], end=' ')
        print()


def odd(magic):
    n = len(magic)
    row = n - 1
    col = n // 2
    magic[row][col] = 1
    for i in range(2, n * n + 1):
        if magic[(row+1) % n][(col+1) % n] == 0:
            row = (row + 1) % n
            col = (col + 1) % n
        else:
            row = (row - 1 + n) % n
        magic[row][col] = i
    return magic


n = int(input("Value Of N? "))
if n == 2:
    sq = [[1, 1], [1, 1]]
    for i in range(len(sq)):
        for j in range(len(sq)):
            print(sq[i][j], end=' ')
        print()
elif n % 2 == 1:
    generateOddSquare(n)
elif n % 4 == 0:
    generateDoublyEvenSquare(n)
else:
    generateSinglyEvenSquare(n)

Now let’s discuss the working of the program given above.

Algorithm Explanation: Magic Square Matrix Of Any Order

This program generates magic squares of all types (of all values of n).

A magic square is a 2D grid of numbers such that the sum of the numbers in each row, column, and diagonal is the same.

The program has three functions: generateOddSquare, generateDoublyEvenSquare, and generateSinglyEvenSquare, which generate magic squares of odd size, doubly even size, and singly even size respectively.

The generateOddSquare function generates magic squares of odd size using the following algorithm.

The function takes in an integer n, which is the size of the magic square (it is assumed that n is odd). It initializes the magic square as a 2D list of zeros with size n by n. Two variables i and j are initialized to be the middle row and column of the square, respectively. A variable num is also initialized to be 1.

The function then enters a while loop that iterates num from 1 to n * n, and fills in the magic square with each iteration. The loop works as follows:

  1. If i is -1 and j is n, it sets j to be n – 2 and i to be 0.
  2. Otherwise, if j is n, it sets j to be 0. If i is less than 0, it sets i to be n – 1.
  3. If the value at position [i][j] in the magic square is already set, it decrements j by 2 and increments i by 1, and continues to the next iteration of the loop.
  4. If the value at position [i][j] in the magic square is not set, it sets this value to num and increments num by 1.
  5. It increments j by 1 and decrements i by 1.

After the while loop has completed, the function prints the magic square using a nested for loop.

This algorithm generates a magic square of odd size by filling it in a spiral pattern, starting from the middle of the square and spiraling outwards. The conditional statements and loop variables are used to ensure that the spiral fills the magic square correctly, even if the indices i and j go out of bounds or encounter already filled cells.

The generateDoublyEvenSquare function generates magic squares of odd size using the following algorithm.

The function takes in an integer n, which is the size of the magic square (it is assumed that n is doubly even, i.e. a multiple of 4). It initializes the magic square as a 2D list containing the integers from 1 to n * n in order, using a list comprehension.

Code snippet

This list comprehension generates a list of rows, where each row is a list of integers from 1 to n in order. The outer for loop iterates over the rows y from 0 to n – 1, and the inner for loop iterates over the columns x from 0 to n – 1. The value at position [y][x] in the magic square is set to (n * y) + x + 1. This generates a list of lists such that the value at position [y][x] in the magic square is equal to y * n + x + 1.

The function then swaps the values in certain positions of the magic square using a series of nested for loops. It has four outer for loops that iterate over the rows and columns of the magic square in blocks of size n//4. The inner for loops iterate over the columns of each block of rows. The function swaps the value at each position with its mirror image across the center of the magic square.

Code snippet

The first outer for loop iterates over the rows i from 0 to n//4 – 1, and the inner for loop iterates over the columns j from 0 to n//4 – 1. This block of code swaps the value at position [i][j] with its mirror image across the center of the magic square. The value at position [i][j] is set to (n * n + 1) – arr[i][j], where arr[i][j] is the original value at this position.

The second outer for loop iterates over the rows i from 0 to n//4 – 1, and the inner for loop iterates over the columns j from 3 * (n//4) to n – 1. This block of code swaps the value at position [i][j] with its mirror image across the center of the magic square. The value at position [i][j] is set to (n * n + 1) – arr[i][j], where arr[i][j] is the original value at this position.

The third outer for loop iterates over the rows i from 3 * (n//4) to n – 1, and the inner for loop iterates over the columns j from 0 to n//4 – 1. This block of code swaps the value at position [i][j] with its mirror image across the center of the magic square. The value at position [i][j] is set to (n * n + 1) – arr[i][j], where arr[i][j] is the original value at this position.

The fourth outer for loop iterates over the rows i from 3 * (n//4) to n – 1, and the inner for loop iterates over the columns j from 3 * (n//4) to n – 1. This block of code swaps the value at position [i][j] with its mirror image across the center of the magic square. The value at position [i][j] is set to (n * n + 1) – arr[i][j], where arr[i][j] is the original value at this position.

After the for loops have completed, the function prints the magic square using a nested for loop.

Code snippet

This for loop iterates over the rows i from 0 to n – 1, and the inner for loop iterates over the columns j from 0 to n – 1. It prints the value at position [i][j] in the magic square, followed by a space.

The generateSinglyEvenSquare function generates magic squares of singly even size using a combination of the algorithms used in the previous two functions.

The function takes in an integer n, which is the size of the magic square (it is assumed that n is singly even, i.e. a multiple of 2 but not a multiple of 4). It first initializes a 2D list magicsqr of zeros with size n by n.

It then defines a variable halfN as n // 2, which is the size of the smaller magic squares that the function will use to generate the final magic square. It defines a variable k as (n – 2) // 4, which will be used later in the function. It also initializes two variables temp and swapCol to be empty, and a variable index to be 0.

The function then generates a magic square of odd size using the generateOddSquare function, and assigns the result to a 2D list miniMagic of size halfN by halfN.

The function then generates a magic square of odd size using the generateOddSquare function, and assigns the result to a 2D list miniMagic of size halfN by halfN.

It then copies the values in miniMagic to the appropriate positions in magicsqr.

The function then performs the following operations to complete the magic square:

  1. It fills the list swapCol with the values from 1 to k + 1 and from n – k + 2 to n + 1. This list will be used later to swap the values in certain columns of the magic square.
  2. It uses two nested for loops to swap the values in certain positions of the magic square. The outer for loop iterates over the rows i from 1 to halfN + 1, and the inner for loop iterates over the indices j of the list swapCol. It swaps the value at position [i – 1][swapCol[j – 1] – 1] with the value at position [i + halfN – 1][swapCol[j – 1] – 1].
  3. It swaps the value at position [k][0] with the value at position [k + halfN][0].
  4. It swaps the value at position [k + halfN][k] with the value at position [k + halfN][k + halfN].
  5. It swaps the value at position [k][k + halfN] with the value at position [k][k].
  6. It defines a variable index as the index of the first value in the list swapCol that is equal to k + 1.
  7. It uses a while loop to swap the values in certain positions of the magic square.

The function then prints the magic square using a nested for loop.

Code snippet.

This for loop iterates over the rows i from 0 to n – 1, and the inner for loop iterates over the columns j from 0 to n – 1. It prints the value at position [i][j] in the magic square, followed by a space.

This algorithm generates a magic square of singly even size by first generating a magic square of odd size using the generateOddSquare function, and then performing a series of swaps to complete the magic square. The for loops are used to iterate over the positions of the magic square and perform the necessary swaps.

Finally, when accepting the value of n from the user, we check whether the number is odd, singly even, or doubly even, and call the generateOddSquare, generateDoubleEvenSquare, or generateSinglyEvenSquare functions accordingly.

I hope this article was helpful to you. If you have any doubts, feel free to comment down below. I’ll try my best to help you out.

Have a great day ahead!

About The Author

Anirban is a full-stack developer and an SEO expert. He has 6 years of experience in web development and software engineering. With a passion for writing, he has been blogging since 2017.

Leave a Comment

Love The Article? You Can