#include <iostream>
#include <set>
using namespace std;
#define SQUARE_SIZE 9
int anyLine = 0;
int currLine = 0;
int numSolutions = 0;
set<int> seen;
// swap two values in the square.
void swap (int arr[], int idxa, int idxb)
{
int tmp = arr[idxa];
arr[idxa] = arr[idxb];
arr[idxb] = tmp;
}
int key(int arr[]) {
return arr[0]
+ 10 * arr[1]
+ 100 * arr[2]
+ 1000 * arr[3]
+ 10000 * arr[4]
+ 100000 * arr[5]
+ 1000000 * arr[6]
+ 10000000 * arr[7]
+ 100000000 * arr[8];
}
void printArray(int arr[])
{
if (!seen.insert(key(arr)).second) return;
numSolutions++;
for (int i = 0; i < SQUARE_SIZE; i++) {
cout << arr[i] << " ";
if((i+1) % 3 == 0)
cout << endl;
}
cout << endl;
}
bool checkArr(int arr[])
{
anyLine = arr[0] + arr[1] + arr[2];
currLine = 0;
for (int i = 0; i < SQUARE_SIZE; i++)
{
currLine += arr[i];
if((i+1) % 3 == 0)
{
if (currLine != anyLine)
return false;
currLine = 0;
}
}
// check vertically
for (int col = 0; col <3; col++)
{
for (int row = 0; row <3; row++)
{
currLine += arr[col + 3 * row];
}
if (currLine != anyLine)
return false;
currLine = 0;
}
// check the diagonals
if ((arr[2] + arr[4] + arr[6]) != anyLine)
return false;
if ((arr[0] + arr[4] + arr[8]) != anyLine)
return false;
return true;
}
void solve(int arr[], int pos)
{
if (pos == 8)
{
if (checkArr(arr))
{
printArray(arr);
}
}else
{
for (int i = 0 ; i < 9; i++)
{
if (i == pos) continue;
swap(arr,pos,i);
solve(arr,pos +1);
}
}
}
int main()
{
int arr[SQUARE_SIZE]= { 1,2,3,4,5,6,7,8,9 };
solve(arr,0);
cout << "number of solutions is: " << numSolutions<< endl << seen.size() << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c2V0Pgp1c2luZyBuYW1lc3BhY2Ugc3RkOwojZGVmaW5lIFNRVUFSRV9TSVpFIDkKCmludCBhbnlMaW5lID0gMDsKaW50IGN1cnJMaW5lID0gMDsKaW50IG51bVNvbHV0aW9ucyA9IDA7CgpzZXQ8aW50PiBzZWVuOwoKLy8gc3dhcCB0d28gdmFsdWVzIGluIHRoZSBzcXVhcmUuCnZvaWQgc3dhcCAoaW50IGFycltdLCBpbnQgaWR4YSwgaW50IGlkeGIpCnsKICBpbnQgdG1wID0gYXJyW2lkeGFdOwogIGFycltpZHhhXSA9IGFycltpZHhiXTsKICBhcnJbaWR4Yl0gPSB0bXA7Cn0KCmludCBrZXkoaW50IGFycltdKSB7CglyZXR1cm4gYXJyWzBdCgkrIDEwICogYXJyWzFdCgkrIDEwMCAqIGFyclsyXQoJKyAxMDAwICogYXJyWzNdCgkrIDEwMDAwICogYXJyWzRdCgkrIDEwMDAwMCAqIGFycls1XQoJKyAxMDAwMDAwICogYXJyWzZdCgkrIDEwMDAwMDAwICogYXJyWzddCgkrIDEwMDAwMDAwMCAqIGFycls4XTsKfQoKIHZvaWQgcHJpbnRBcnJheShpbnQgYXJyW10pCiB7CiAJaWYgKCFzZWVuLmluc2VydChrZXkoYXJyKSkuc2Vjb25kKSByZXR1cm47CiAgICBudW1Tb2x1dGlvbnMrKzsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgU1FVQVJFX1NJWkU7IGkrKykgewogICAgICAgIGNvdXQgPDwgYXJyW2ldIDw8ICIgIjsKICAgICAgICBpZigoaSsxKSAlIDMgPT0gMCkKICAgICAgICAgICAgY291dCA8PCBlbmRsOwogICAgfQogICAgY291dCA8PCBlbmRsOwogfQoKYm9vbCBjaGVja0FycihpbnQgYXJyW10pCnsKICBhbnlMaW5lID0gYXJyWzBdICsgYXJyWzFdICsgYXJyWzJdOwogIGN1cnJMaW5lID0gMDsKICBmb3IgKGludCBpID0gMDsgaSA8IFNRVUFSRV9TSVpFOyBpKyspCiAgewogICAgY3VyckxpbmUgKz0gYXJyW2ldOwogICAgaWYoKGkrMSkgJSAzID09IDApCiAgICB7CiAgICAgICAgaWYgKGN1cnJMaW5lICE9IGFueUxpbmUpCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIGN1cnJMaW5lID0gMDsKICAgIH0KICB9CiAgLy8gY2hlY2sgdmVydGljYWxseQogIGZvciAoaW50IGNvbCA9IDA7IGNvbCA8MzsgY29sKyspCiB7CiAgICBmb3IgKGludCByb3cgPSAwOyByb3cgPDM7IHJvdysrKQogICAgewogICAgICAgIGN1cnJMaW5lICs9IGFycltjb2wgKyAzICogcm93XTsKICAgIH0KICAgIGlmIChjdXJyTGluZSAhPSBhbnlMaW5lKQogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICBjdXJyTGluZSA9IDA7CiAgfQoKICAvLyBjaGVjayB0aGUgZGlhZ29uYWxzCiAgaWYgKChhcnJbMl0gKyBhcnJbNF0gKyBhcnJbNl0pICE9IGFueUxpbmUpCiAgICByZXR1cm4gZmFsc2U7CgogIGlmICgoYXJyWzBdICsgYXJyWzRdICsgYXJyWzhdKSAhPSBhbnlMaW5lKQogICAgcmV0dXJuIGZhbHNlOwoKICByZXR1cm4gdHJ1ZTsKIH0KCiB2b2lkIHNvbHZlKGludCBhcnJbXSwgaW50IHBvcykKIHsKCiAgaWYgKHBvcyA9PSA4KQogewoKIGlmIChjaGVja0FycihhcnIpKQogewogICAgcHJpbnRBcnJheShhcnIpOwogfQoKfWVsc2UKewpmb3IgKGludCBpID0gMCA7IGkgPCA5OyBpKyspCnsgCiAgICBpZiAoaSA9PSBwb3MpIGNvbnRpbnVlOwogICAgICAgc3dhcChhcnIscG9zLGkpOwogICAgICAgc29sdmUoYXJyLHBvcyArMSk7CgogICAgfQogIH0KfQoKaW50IG1haW4oKQp7CgppbnQgYXJyW1NRVUFSRV9TSVpFXT0geyAxLDIsMyw0LDUsNiw3LDgsOSB9OwoKc29sdmUoYXJyLDApOwpjb3V0IDw8ICJudW1iZXIgb2Ygc29sdXRpb25zIGlzOiAiIDw8IG51bVNvbHV0aW9uczw8IGVuZGwgPDwgc2Vlbi5zaXplKCkgPDwgZW5kbDsKCnJldHVybiAwOwp9