简体   繁体   中英

Returning array in C, Sudoku Solver

So I'm creating a sudoku solver in C. Here's my full code as of now, I've mostly been using python and just got into C, I basically converted a lot of python functions to C to get this but I think it'll work:

#include <stdio.h>
#include <stdlib.h>

int is_empty();
int possible_v();
int solver();

int main(){
    int s_array[9][9];
    FILE * fpointer;
    int i;
    int j;

    fpointer = fopen("sudoku001.txt", "r");

    for (i=0; i<9; i++){
        for(j = 0; j<9; j++){
            fscanf(fpointer, "%d", &s_array[i][j]);
        }
    }

    for (i=0; i<9; i++) {
        if (i % 3 == 0) {
            printf("------------------------------\n");
        }

        for (j = 0; j < 9; j++) {
            printf(" %d ", s_array[i][j]);
            if ((j + 1) % 3 == 0) {
                printf("|");
            }
        }
        printf("\n");
    }



    solver(s_array);

    for (i=0; i<9; i++) {
        if (i % 3 == 0) {
            printf("------------------------------\n");
        }

        for (j = 0; j < 9; j++) {
            printf(" %d ", s_array[i][j]);
            if ((j + 1) % 3 == 0) {
                printf("|");
            }
        }
        printf("\n");
    }
    return 0;


}

int is_empty(int board[9][9]){
    int i;
    int j;
    int is_empty= 0;
    for (i=0; i<9; i++){
        for(j = 0; j<9; j++){
            if (board[i][j] == 0) {
                is_empty = 1;
                break;
            }
        }
        if (is_empty == 1){
            break;
        }
    }
    return is_empty;
}

int possible_v(int board[9][9], int i, int j) {
    int p_array[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
    int x;
    int y;
    int temp;

    for (x = 0; x < 9; x++) {
        if (board[x][j] != 0) {
            temp = board[x][j];
            p_array[temp - 1] = temp;
        }
    }
    for (y = 0; y < 9; y++) {
        if (board[i][y] != 0) {
            temp = board[i][y];
            p_array[temp - 1] = temp;
        }
    }

    int m;
    int n;
    int temp1;
    int temp2;
    if (i>= 0 && i <= 2) {
        m = 0;
    }
    else if (i>= 3 && i<=5) {
        m = 3;
    }
    else{
        m = 6;
    }

    if (j>= 0 && j <= 2) {
        n = 0;
    }
    else if (j>= 3 && j<=5) {
        n = 3;
    }
    else{
        n = 6;
    }

    temp1 = m;
    temp2 = n;

    for (temp1; temp1<temp1+3; temp1++){
        for (temp2; temp2<temp2+3; temp2++){
            if (board[temp1][temp2] != 0){
                p_array[board[temp1][temp2]] = 1;
            }
        }
    }
    temp1 = 1;
    for (temp1; temp1<10){
        if (p_array[temp1] == 0){
            p_array[temp1] = temp1;
        }
        else{
            p_array[temp1] = 0;
        }
    }
    return p_array;
}

int solver(int board[9][9]){
    int i;
    int j;
    int x;
    int y;
    int empty_check;
    int p_values;
    int temp;

    if (is_empty(board) == 0){
       printf("Board Completed");
       empty_check = 0;
       return empty_check;
    }
    else{
        for (x = 0; x < 9; x++){
            for (y = 0; y< 9; y++){
                if (board[x][y] == 0){
                    i = x;
                    j = y;
                    break;
                }
            }
        }
        p_values = possible_v(board, i, j);

        for (temp = 1; temp <10; temp++){
            if (p_values[temp] != 0){
                board[i][j] = p_values[temp];
                solver(board);
            }
        }
        board[i][j] = 0;
    }
}

My main issue when compiling is getting the last two functions work with each other.

Function 'solver' calls and binds function 'possible_v'. Possible_V returns an array which I need to solve the puzzle. How can I make this work? .

You have the array locally declared, hence it cannot be passed back since it is destroyed once the function is exited. The workaround to this is to dynamically declare the array using malloc int *parray = (int*)malloc(9*sizeof(int)); and using the return type int* instead of int . But do not forget to free the allocated memory, else you will just keep allocating new memory from heap for every call you make.

As a side note, your implementation of Sudoku solver is a bit complex, and there is no need to return an array. You need to pass only the board. Here is an implementation of Sudoku Solver. This works both for 9x9 and 6X6 boards.

Edit : As advised by David Rankin, I have converted the C++ code to C.

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

int n;

int issafe(int **board,int i,int j,int num){

  for(int k=0;k<n;k++)
    if(board[i][k] == num || board[k][j] == num)
     return 0;

  int cellx,celly;
  if(n==6){

   cellx = (i/2)*2;
   celly = (j/3)*3;

   for(int l=cellx;l<cellx+2;l++)
     for(int m=celly;m<celly+3;m++)
      if(board[l][m] == num){
        return 0;
      }

   return 1;
 }

 int root = sqrt(n);
 cellx = (i/(root))*root;
 celly = (j/(root))*root;

 for(int l=cellx;l<cellx+root;l++)
  for(int m=celly;m<celly+root;m++)
    if(board[l][m] == num)
     return 0;

 return 1;
}

int solve(int **board,int i,int j){

  if(i == n)
    return 1;

  if(j == n){
    return solve(board,i+1,0);
  }

  if(board[i][j] != 0)
    return solve(board,i,j+1);

  for(int k=1;k<n+1;k++)
    if(issafe(board,i,j,k)){
      board[i][j] = k;
      if(solve(board,i,j+1))
        return 1;
      //backtrack
      board[i][j] = 0;
    }

  return 0;
}

int main(){

  do{
    printf("Enter size of board(9 or 6): ");
    scanf("%d",&n);
  }while(n != 9 && n != 6);

  int **board;
  board = malloc(sizeof *board * n);
  for(int i=0;i<n;i++)
    board[i] = malloc(sizeof *board * n);

  // input
  for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      scanf("%d",&board[i][j]);

  if(solve(board,0,0))
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++)
        printf("%d ",board[i][j]);
      printf("\n");
    }
  return 0;
}

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