Minimum cost to convert 3 X 3 matrix into magic square

A Magic Square is a n x n matrix of distinct element from 1 to n2 where the sum of any row, column or diagonal is always equal to same number.
Consider a 3 X 3 matrix, s, of integers in the inclusive range [1, 9] . We can convert any digit, a, to any other digit, b, in the range [1, 9] at cost |a – b|.
Given s, convert it into a magic square at minimal cost by changing zero or more of its digits. The task is to find minimum cost.
Note: The resulting matrix must contain distinct integers in the inclusive range [1, 9].

Examples:

```Input : mat[][] = { { 4, 9, 2 },
{ 3, 5, 7 },
{ 8, 1, 5 }};
Output : 1
Given matrix s is not a magic square. To convert
it into magic square we change the bottom right
value, s[2][2], from 5 to 6 at a cost of | 5 - 6 |
= 1.

Input : mat[][] = { { 4, 8, 2 },
{ 4, 5, 7 },
{ 6, 1, 6 }};
Output : 4
```

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

The idea is to find all 3 X 3 magic squares and, for each one, compute the cost of changing mat into a known magic square. The result is the smallest of these costs.
We know that s will always be 3 X 3. There are 8 possible magic squares for 3 X 3 matrix.
There are two ways to approach this:
So, compute all 8 magic squares by examining all permutations of integers 1, 2, 3, ….., 9 and for each one, check if it forms a magic square if the permutation is inserted into the square starting from the upper left hand corner.

Below is C++ implementation of this approach:

```#include <bits/stdc++.h>
using namespace std;

// Return if given vector denote the magic square or not.
bool is_magic_square(vector<int> v)
{
int a[3][3];

// Convert vector into 3 X 3 matrix
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
a[i][j] = v[3 * i + j];

int s = 0;
for (int j = 0; j < 3; ++j)
s += a[0][j];

// Checking if each row sum is same
for (int i = 1; i <= 2; ++i) {
int tmp = 0;
for (int j = 0; j < 3; ++j)
tmp += a[i][j];
if (tmp != s)
return 0;
}

// Checking if each column sum is same
for (int j = 0; j < 3; ++j) {
int tmp = 0;
for (int i = 0; i < 3; ++i)
tmp += a[i][j];
if (tmp != s)
return 0;
}

// Checking if diagonal 1 sum is same
int tmp = 0;
for (int i = 0; i < 3; ++i)
tmp += a[i][i];
if (tmp != s)
return 0;

// Checking if diagnol 2 sum is same
tmp = 0;
for (int i = 0; i < 3; ++i)
tmp += a[2 - i][i];
if (tmp != s)
return 0;
return 1;
}

// Generating all magic square
void find_magic_squares(vector<vector<int> >& magic_squares)
{
vector<int> v(9);

// Initialing the vector
for (int i = 0; i < 9; ++i)
v[i] = i + 1;

// Producing all permutation of vector
// and checking if it denote the magic square or not.
do {
if (is_magic_square(v)) {
magic_squares.push_back(v);
}
} while (next_permutation(v.begin(), v.end()));
}

// Return sum of difference between each element of two vector
int diff(vector<int> a, vector<int> b)
{
int res = 0;

for (int i = 0; i < 9; ++i)
res += abs(a[i] - b[i]);

return res;
}

// Wrapper function
int wrapper(vector<int> v)
{
int res = INT_MAX;
vector<vector<int> > magic_squares;

// generating all magic square
find_magic_squares(magic_squares);

for (int i = 0; i < magic_squares.size(); ++i) {

// Finding the difference with each magic square
// and assigning the minimum value.
res = min(res, diff(v, magic_squares[i]));
}
return res;
}

// Driven Program
int main()
{
// Taking matrix in vector in rowise to make
// calculation easy
vector<int> v;
v.push_back(4);
v.push_back(9);
v.push_back(2);

v.push_back(3);
v.push_back(5);
v.push_back(7);

v.push_back(8);
v.push_back(1);
v.push_back(5);

cout << wrapper(v) << endl;

return 0;
}
```

Output:

```1
```

This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.
0 Average Difficulty : 0/5.0