简体   繁体   中英

Sudoku solver in C not working properly

I've written this Sudoku solver in C. But it isn't working properly, Any help?

With a sample input such as

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

it gives output

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

Any idea what went wrong?

#include<stdio.h>

int sudoku[9][9];

int check(int sudoku[][9], int row, int col, int sol)
{
    //checking in the grid
    int row_grid = (row/3) * 3;
    int col_grid = (col/3) * 3;

    int i, j;
    for(i=0; i<9; ++i)
    {
        if (sudoku[row][i] == sol)                             
            return 0;
        if (sudoku[i][col] == sol)                             
            return 0;
        if (sudoku[row_grid + (i%3)][col_grid + (i/3)] == sol) 
            return 0;
    }
    return 1;
}  


int main(void)
{
    int i,j,k;
    printf("enter the sudoku and enter 0 for unknown entries \n");
    for(i=0;i<9;i++)
    {
        for (j=0;j<9;j++)
        {
            scanf("%d",&sudoku[i][j]);
        }
    }    
    for(i=0;i<9;i++)
    {
        for (j=0;j<9;j++)
        {
            if(sudoku[i][j]==0)
            {
                for (k=1;k<=9;k++)
                {
                    if(check(sudoku,i,j,k)==1)
                    {
                        sudoku[i][j] = k;                   
                    }
                }               
            }
        }
    }

    printf("solved sudoku \n");
    for(i=0;i<9;i++)
    {
        for (j=0;j<9;j++)
        {
            printf("%d ", sudoku[i][j]);
        }
        printf("\n");       
    }
    return 0;
}

You aren't going to solve a sudoku this way. You just loop through all cells and for each empty cell you pick the biggest value that can be there. Obviously, it is incorrect, since there might be several variants in one cell. And you always pick the biggest (since there is no break in a for (k=...) loop). Sometimes you pick the wrong number and it makes a sudoku inconsistent.

UPDATE: what you do is not a brute-force, since you don't iterate through all possible solutions. Instead of

if(check(sudoku,i,j,k)==1)
{
    sudoku[i][j] = k;                   
}

There must be something like

if(check(sudoku,i,j,k)==1)
{
    tempSudoku = copy(sudoku); //pseudocode
    tempSudoku[i][j] = k;
    tryToSolveRecursively(tempSudoku);              
}

If check() returned 0, then there is an inconsistency (for some empty cell we can't find a single possible solution). And so we should abandon this solution, go back and try something else (viva la recursion :) ). This is not an only option, but I just hope that it will point you in a right direction.

PS Brute force solution based just on basic sudoku rules will be terribly slow . Trust me. You need additional heuristics to reduce the search space.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM