Code:
#include <stdio.h>
#include <stdlib.h>
void RemovePossNum(int, int, int, int [][9][9] );
void GetRegion( int, int, int *, int * );
void RemoveNumRegion( int, int, int, int [][9][9] );
void printSoloution(int [][9] );
void printPossibleNumbers( int [][9][9] );
void SolvedCell( int, int, int, int [][9][9], int [][9] );
int NakedSingles( int [][9][9], int [][9] );
int FindNakedSingle( int, int, int [][9][9], int [][9] );
int HiddenSingles( int [][9][9], int [][9] );
void FindHiddenSingles( int, int, int *, int [][9][9], int [][9] );
int GetHiddenSingles( int, int, int *, int [][9][9], int [][9] );
int main()
{
int PossibleNums[9][9][9] = {{{ 0 }}}, Soloution[9][9] = {
{ 5, 0, 0, 0, 7, 8, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 4, 0, 0 },
{ 0, 0, 8, 0, 9, 0, 1, 0, 7 },
{ 0, 0, 7, 0, 0, 0, 0, 4, 0 },
{ 2, 0, 0, 1, 0, 0, 7, 0, 6 },
{ 0, 0, 0, 0, 6, 0, 0, 5, 0 },
{ 0, 3, 0, 2, 0, 0, 0, 0, 0 },
{ 0, 0, 5, 0, 1, 0, 8, 0, 9 },
{ 0, 0, 0, 0, 0, 0, 0, 6, 0 }};
for ( int i = 0; i < 9; i++ )
for ( int j = 0; j < 9; j++ )
for ( int k = 0; k < 9; k++ )
if ( Soloution[i][j] == 0 )
PossibleNums[i][j][k] = k + 1;
//printPossibleNumbers(PossibleNums);
int NumcellsSolved = 0;
for ( int i = 0; i < 9; i++ )
for ( int j = 0; j < 9; j++ )
{
if ( Soloution[i][j] )
{
RemovePossNum( i, j, Soloution[i][j], PossibleNums );
NumcellsSolved++;
}
}
printSoloution( Soloution );
printf("number of solved cells is %d\n", NumcellsSolved);
int x = 0;
while (NumcellsSolved < 81 )
{
x = NumcellsSolved;
NumcellsSolved += NakedSingles( PossibleNums, Soloution );
NumcellsSolved+= HiddenSingles( PossibleNums, Soloution );
printf("number of solved cells is %d\n", NumcellsSolved);
if (x == NumcellsSolved ) break;
}
printSoloution( Soloution );
printPossibleNumbers( PossibleNums );
printf("number of solved cells is %d\n", NumcellsSolved);
return 0;
}
void RemovePossNum(int Row, int Column, int NumRemove, int PNum[][9][9] )
{
int x, y;
for ( int i = 0; i < 9; i++ )
PNum[Row][i][NumRemove - 1] = 0;
for ( int i = 0; i < 9; i++ )
PNum[i][Column][NumRemove - 1] = 0;
GetRegion( Row, Column, &x, &y );
RemoveNumRegion( x, y, NumRemove, PNum );
}
void GetRegion( int Row, int Column, int *x, int *y )
{
*x = Row / 3 * 3;
*y = Column / 3 * 3;
}
void RemoveNumRegion( int x, int y, int RemoveNum, int Pnum[][9][9])
{
for (int i = x; i < x + 3; i++ )
for ( int j = y; j < y + 3; j++ )
Pnum[i][j][RemoveNum - 1] = 0;
}
void printSoloution(int Soloution[][9] )
{
for ( int i = 0; i < 9; i++ )
{
if ( i % 3 == 0 )
putchar('\n');
for ( int j = 0; j < 9; j++ )
{
if ( j % 3 == 0 )
putchar('\t');
if ( Soloution[i][j] )
printf("%d ", Soloution[i][j]);
else
printf("- ");
}
putchar('\n');
}
putchar('\n');
}
void printPossibleNumbers( int PossNum[][9][9] )
{
for ( int i = 0; i < 9; i++ )
for ( int j = 0; j < 9; j++ )
{
printf("i = %d j = %d possibles = ", i, j);
for ( int k = 0; k < 9; k++)
if ( PossNum[i][j][k] )
printf("%d ", PossNum[i][j][k]);
putchar('\n');
}
}
void SolvedCell( int Row, int Column, int Answer, int pNum[][9][9], int Solved[][9] )
{
Solved[Row][Column] = Answer;
RemovePossNum( Row, Column, Answer, pNum );
for ( int i = 0; i < 9; i++ )
pNum[Row][Column][i] = 0;
}
int NakedSingles( int PossNum[][9][9], int Solved[][9] )
{
int CellsSolved = 0;
for ( int Row = 0; Row < 9; Row++ )
for ( int Column = 0; Column < 9; Column++ )
CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
for ( int Column = 0; Column < 9; Column++ )
for ( int Row = 0; Row < 9; Row++ )
CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved ); //row and column stay in the same order
for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
return CellsSolved;
}
int FindNakedSingle( int Row, int Column, int PossNum[][9][9], int Solved[][9] )
{
int CellsSolved = 0;
if ( !Solved[Row][Column] )
{
int CountPossibleDigits = 0, tmpNum;
for ( int Digit = 0; Digit < 9; Digit++ )
{
if ( PossNum[Row][Column][Digit] )
{
CountPossibleDigits++;
tmpNum = Digit + 1;
}
if (CountPossibleDigits == 2 ) break;
}
if ( CountPossibleDigits == 1 )
{
SolvedCell( Row, Column, tmpNum, PossNum, Solved );
CellsSolved++;
}
}
return CellsSolved;
}
int HiddenSingles( int PossNum[][9][9], int Solved[][9] )
{
int CellsSolved = 0;
for ( int Row = 0; Row < 9; Row++ )
{
int CountDigits[9] = { 0 };
for ( int Column = 0; Column < 9; Column++ )
FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
for ( int Column = 0; Column < 9; Column++ )
CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
}
for ( int Column = 0; Column < 9; Column++ )
{
int CountDigits[9] = { 0 };
for ( int Row = 0; Row < 9; Row++ )
FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
for ( int Row = 0; Row < 9; Row++ )
CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
}
return CellsSolved;
}
void FindHiddenSingles( int Row, int Column, int *CountDigits, int PossNum[][9][9], int Solved[][9] )
{
if ( !Solved[Row][Column] )
for ( int PossDigit = 0; PossDigit < 9; PossDigit++ )
if ( PossNum[Row][Column][PossDigit] )
CountDigits[ PossNum[Row][Column][PossDigit] - 1 ] += 1;
}
int GetHiddenSingles( int Row, int Column, int *CountedDigits, int PossNum[][9][9], int Solved[][9])
{
int CellsSolved = 0;
for ( int Digit = 0; Digit < 9; Digit++ )
if ( CountedDigits[Digit] == 1 )
//for ( int Column = 0; Column < 9; Column++ )
if ( PossNum[Row][Column][Digit] == Digit + 1 )
{
SolvedCell( Row, Column, Digit + 1, PossNum, Solved );
CellsSolved++;
break;
}
return CellsSolved;
}