-5

i'm writing c code to check whether given matrix is valid sudoku solution or not. Input would be matrix of n*n size. I have written code to check row and column but i'm not getting how to validate grids of sqrt(n)*sqrt(n) size.

my code is here

#include<stdio.h>
int main()
{
  int i,j,count=0,sumrow;
  int sumcol;
    int n;
 scanf("%d",&n);
  int arr[n+1][n+1];
  for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
      scanf("%d",&arr[i][j]);
    for(i=1;i<=n;i++)
    {
      sumcol=0;
      for(j=1;j<=n;j++)
      sumcol+=arr[j][i];
      if(sumcol!=(n*(n+1)/2))
        count++;
    }
 for(i=1;i<=n;i++)
  {
    sumrow=0;
    for(j=1;j<=n;j++)
    {
      sumrow+=arr[i][j];
    }
  //    printf("%d\n",sumrow);
    if(sumrow!=(n*(n+1)/2))
      count++;
  }


  //printf("count%d ",count);
  if(count==0)
    printf("yes");
  else
    printf("no");
  return 0;
}
amit
  • 1
  • 1
  • 2
  • 4

4 Answers4

1

Here i have a better solution. Instead of sum, we can use an integer flag.

//read sudoku
for(i=0;i<9;i++)
    for(j=0;j<9;j++)
    {
    scanf("%c",&c);
    a[i][j]=c-'0';
    }
//checking rows
for(i=0;i<9;i++)
    {
    flag=0x0000;
    for(j=0;j<9;j++)
        flag|=1<<(a[i][j]-1);
    if(flag!=0x01FF)
        report("row",i,j-1);
    }

//checking cols
for(j=0;j<9;j++)
    {
    flag=0x0000;
    for(i=0;i<9;i++)
        flag|=1<<(a[i][j]-1);
    if(flag!=0x01FF)
        report("col",i-1,j);
    }
//checking Squares (3x3)
for(si=0;si<3;si++)
    {
    for(sj=0;sj<3;sj++)
        {
        flag=0x0000;
        for(i=0;i<3;i++)
            {
            for(j=0;j<3;j++)
                flag|=1<<(a[si*3+i][sj*3+j]-1);

            }
        if(flag!=0x01FF)
                report("square",si*3+i-1,sj*3+j-1);
        }
    }
printf("\nThe sudoku is correct");

For detailed description, You may visit this link

Mohammed Shareef C
  • 3,829
  • 25
  • 35
0

You can check each of the smaller squares whether they are valid or not.For example if n=9 you have to check each of the 3 by 3 squares.To check each smaller square you can use an array of 10 elements and check whether any of the 1 to 9 value is repeated or not.

The algorithm is as follows

  for each of the smaller grids
      if(any of the digit repeats in a smaller grid)
      return 0;
  return 1;//valid

Following is some code to do the same

  //A is the grid
  int small=sqrt(n);
  for(int i=0;i<small;i++)
  {
     for(int j=0;j<small;j++)
     {
        int row=small*i;//this will find the corresponding row
        int col=small*j;//this will find the corresponding column
        vector<int> used(10,0)
        for(int p=row; p<row+small; p++) {
                for(int q=col; q<col+small; q++) 
                {
                    if(A[p][q]=='0')//0 is not valid
                    return 0;
                    if(used[A[p][q]-'0']==1)//this digit has already been used
                    return 0;
                    if(used[A[p][q]-'0']) return 0;
                    used[A[p][q]-'0']=1;//now this particular digit has occurred and should not occur again
                }
         }
      }
 }
 //if all's well return 1
 return 1;

Note that the above code assumes that entire grid is filled and is not empty.If you want to check a partially filled grid,introduce a check.

Gaurav Sehgal
  • 7,422
  • 2
  • 18
  • 34
0
bool validateMatrix(int g_iMatrix1[][MAXCOLS],
                     int iROWS,
                     int iCOLS)
{
    bool bRowUsed[MAXROWS][MAXCOLS]   = {0};
    bool bColUsed[MAXROWS][MAXCOLS]   = {0};
    bool bBlockUsed[MAXROWS][MAXCOLS] = {0};

    //Matrix to keep record if current value is already set in current row..
    memset(bRowUsed, false, (MAXROWS) * (MAXCOLS));

    //Matrix to keep record if current value is already set in current column..
    memset(bColUsed, false, (MAXCOLS) * (MAXCOLS));

    //Matrix to keep record if current value is already set in current block of iSQRT * iSQRT..
    //Lets assume the matrix is of size 9 * 9..
    //So there will be 9 block of 3 * 3..
    //Number the blocks from left to right as 0 to 8..
    //We will be mapping 0 the block to 0th row, 1st block to 1st row, 2nd block to 2nd row and so on..
    memset(bBlockUsed, false, (MAXROWS) * (MAXCOLS));

    int iRows = 0,iCols = 0;
    int iSQRT = int(sqrt(MAXCOLS));

    for(iRows = 0;iRows < iROWS;iRows++)
    {
        for(iCols = 0;iCols < iCOLS;iCols++)
        {
            if(bRowUsed[iRows][g_iMatrix1[iRows][iCols] - 1] == true)   
            {
                return false;
            }
            if(bColUsed[g_iMatrix1[iRows][iCols] - 1][iCols] == true)
            {
                return false;
            }

            //Number the blocks from left to right as 1 to 9..
            //We will be mapping 0 the block to 0th row, 1st block to 1st row, 2nd block to 2nd row and so on..
            //((iRows / iSQRT) * iSQRT) + (iCols / iSQRT) will map the block with above logic..
            if(bBlockUsed[((iRows / iSQRT) * iSQRT) + (iCols / iSQRT)][g_iMatrix1[iRows][iCols] - 1] == true)
            {
                return false;
            }

            bRowUsed[iRows][g_iMatrix1[iRows][iCols] - 1] = true;
            bColUsed[g_iMatrix1[iRows][iCols] - 1][iCols] = true;
            bBlockUsed[((iRows / iSQRT) * iSQRT) + (iCols / iSQRT)][g_iMatrix1[iRows][iCols] - 1] = true;
        }
    }

    return true;
}
dam0055
  • 69
  • 3
  • Thank you for this code snippet, which might provide some limited short-term help. A proper explanation [would greatly improve](//meta.stackexchange.com/q/114762) its long-term value by showing *why* this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Toby Speight Jan 23 '18 at 10:45
0
int main() {
    int a[10][10],i,j,n,k,sum,sum1,sum2,sum3,x,l;
    printf("enter the size N of N*N sudoku\n");
    scanf("%d",&n);
    printf("enter the entries of sudoku row wise \n");
    for (i=1;i<=n;i++) {
        for (j=1;j<=n;j++) {
            scanf("%d",&a[i][j]);
        }
        printf("\n");
    }
    printf("---------------------------------\n\n\n\n");
    printf("the matrix you entered is \n");
    for (i=1;i<=n;i++) {
        for (j=1;j<=n;j++) {
            printf("%d",a[i][j]);
            printf("|");
        }
        printf("\n");
    }
    for (i=1;i<=n;i++) {
        for (k=i;k==i;k++) {
            sum=0;
            for (j=1;j<=n;j++) {
                sum = sum + a[i][j];
            }

            if(sum!=45)
                x=1;
        }
    }

    for (j=1;j<=n;j++) {
        for(k=j;k==j;k++) {
            sum=0;
            for (i=1;i<=n;i++) {
                sum = sum+a[i][j];
            }
            if (sum!=45)
                x=1;
        }
    }

    for (k=1;k<=3;k++) {
        l = (1+(k-1)*n/3);
        for (i=l;i<=k*n/3;i++) {
            for(j=1;j<=3;j++) {
                sum1 = sum1+a[i][j];
            }
            for (j=4;j<=6;j++) {
                sum2 = sum2+a[i][j];
            }
            for (j=7;j<=9;j++) {
                sum3 = sum3+a[i][j];
            }
        }
        if (sum1!=45||sum2!=45||sum3!=45)
            x=1;
    }
    if (x==1)
        printf("sudoku not correct \n");
    else
        printf("correct sudoku");

    return 0;
}
pushkin
  • 9,575
  • 15
  • 51
  • 95