Count Magic squares in a grid in C++

We are given with a matrix of numbers. The goal is to find the number of Magic squares present inside the given matrix.

A Magic Square, if taken as a matrix, is a 3X3 matrix which contains the elements ranging from 1 to 9 just like a grid in Sudoku. Properties are −

• All numbers occur exactly once.
• Sum of all 9 cells in the matrix is 45.
• Sum of each row of 3 is 15.
• Sum of each column of 3 is 15.
• Sum of diagonals of 3 is 5.
• To get such sums, 5 is always in the middle of both diagonals.

Input

int arr[][]= { { 1,2,3,0 }, { 4,5,6,1 }, { 7,8,9,0 } };

Output

Magic Squares present: 0

Explanation − Making a matrix form to understand −

 1 2 3 0 4 5 6 1 7 8 9 0

All elements are between 1 to 9 and are unique. But,

1+2+3=6 != 4+5+6=15 != 7+8+9=23

Also diagonals sum is not equal to 15.

Input

arr[][]= { { 1,2,3,0 }, { 4,5,6,1 }, { 7,8,9,0 } };

Output

Magic Squares present : 1

Explanation − Making a matrix form to understand −

 1 6 8 4 8 1 6 0 3 5 7 1 4 9 2 0

All numbers are unique and in the range 1 to 9.

Rows sum, 8+1+6=3+5+7=4+9+2=15

Columns sum, 8+3+4=1+5+9=6+7+2=15

Diagonals sum, 8+5+2=4+5+6=15

Also adding 1 to 9 we get 45, and 5 is middle of both diagonals.

Approach used in the below program is as follows

• Integer array Grid[][] stores the numbers, row and col stores its dimensions.

• Function magicSquare(int a, int b…..int i) takes all 9 elements as input and checks if it makes the magic square. Returns 1 if it is magic square, returns 1 otherwise.

• Here we will take array arr[9] to store all parameters and check if they are unique by checking that they occupy unique cells in it. If a cell has count<1 means no. is not in range of 1 to 9, or if count>1 then no. is not unique. set flag=0

• If flag is 1 then we will check for row, column, diagonal sums as 15. If true then it is a magic square.Return 1 else return 0.

• Function countSquares (int G[3][4],int R, int C) takes a grid, its rows and columns as input and counts the no. of magic squares present in it.

• Count is used to store count of the number of such squares.

• Start traversing from first element till row-2, col-2 ( 3X3 matrix )

• If the middle of diagonal G[i+1][j+1] is not 5 then magic square is not possible, skip the current iteration.

• Else check for all 9 elements by passing it to magicSquare( int a to i )

• All 9 elements including G[i][j] are G[i+1][j], G[i+2][j], G[i+1][j+1],G[i][j+1],G[i][j+2],G[i+2][j+2],G[i+2][j+1], G[i+1][j+2]

• If it returns 1 increase count.

• In the end return count as desired result.

Example

Live Demo

#include <bits/stdc++.h>
using namespace std;
// to check is subgrid is Magic Square
int magicSquare(int a, int b, int c, int d, int e,
int f, int g, int h, int i){
int flag=1; // to mark all numbers are unique and between 1 to 9
int arr[9]={0};
arr[a-1]++;
arr[b-1]++;
arr[c-1]++;
arr[d-1]++;
arr[e-1]++;
arr[f-1]++;
arr[g-1]++;
arr[h-1]++;
arr[i-1]++;
for(int i=0;i<9;i++)
if(arr[i]>1 || arr[i]<1) //every number occurs exactly once{
flag=0;
break;
}
// checking all sums as 15
if (flag==1 && (a + b + c) == 15 && (d + e + f) == 15 && (g + h + i) == 15 && (a + d + g) == 15 &&(b + e + h) == 15 && (c + f + i) == 15 &&(a + e + i) == 15 && (c + e + g) == 15)
return 1;
return 0;
}
int countSquares(int G[3][4],int R, int C){
int count = 0;
for (int i = 0; i < R - 2; i++)
for (int j = 0; j < C - 2; j++) {
if (G[i + 1][j + 1] != 5)
continue;
int ismagic=magicSquare(G[i][j], G[i][j + 1], G[i][j + 2], G[i + 1][j], G[i + 1][j + 1],
G[i + 1][j + 2], G[i + 2][j], G[i + 2][j + 1], G[i + 2][j + 2]);
// check for magic square subgrid
if (ismagic==1)
count++;
}
return count;
}
int main(){
int Grid[3][4] = { { 4, 3, 8, 4 },{ 9, 5, 1, 9 },{ 2, 7, 6, 2 } };
int row=3;
int col=4;
cout <<"Count of Magic Squares in Grid: "<<countSquares(Grid,row,col);
return 0;
}

Output

Count of Magic Squares in Grid: 1