Question

What is a C code solution for solving Sudoku using size relationships?

Answer and Explanation

A Sudoku solver in C typically uses backtracking to explore possible solutions. Size relationships (i.e., a number cannot be repeated in a row, column, or 3x3 box) are enforced at each step to prune the search space, dramatically improving efficiency. Here's a complete C code example:

This C code implements a Sudoku solver using a backtracking algorithm. It enforces the size relationships of Sudoku by checking for number conflicts in rows, columns, and 3x3 subgrids. The 'isSafe' function evaluates these constraints before attempting to place a number.

Here's the complete C code example:

#include <stdio.h>
#include <stdbool.h>

#define N 9

// Function to print the Sudoku grid
void printGrid(int grid[N][N]) {
  for (int row = 0; row < N; row++) {
    for (int col = 0; col < N; col++) {
      printf("%d ", grid[row][col]);
    }
    printf("\\n");
  }
}

// Function to check if it is safe to place a number in the grid
bool isSafe(int grid[N][N], int row, int col, int num) {
  // Check if the number is already present in the row
  for (int x = 0; x < N; x++)
    if (grid[row][x] == num)
      return false;

  // Check if the number is already present in the column
  for (int x = 0; x < N; x++)
    if (grid[x][col] == num)
      return false;

  // Check if the number is already present in the 3x3 box
  int startRow = row - row % 3;
  int startCol = col - col % 3;
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (grid[i + startRow][j + startCol] == num)
        return false;

  return true;
}

// Function to find an unassigned location
bool findUnassignedLocation(int grid[N][N], int row, int col) {
  for (row = 0; row < N; (row)++)
    for (col = 0; col < N; (col)++)
      if (grid[row][col] == 0)
        return true;
  return false;
}

// Recursive function to solve Sudoku
bool solveSudoku(int grid[N][N]) {
  int row, col;

  // If there is no unassigned location, we are done
  if (!findUnassignedLocation(grid, &row, &col))
    return true; // Success!

  // Consider digits 1 to 9
  for (int num = 1; num <= N; num++) {
    // If there is no conflict for digit num at row, col
    if (isSafe(grid, row, col, num)) {
      // Make tentative assignment
      grid[row][col] = num;

      // Return, if success
      if (solveSudoku(grid))
        return true;

      // Failure, unmake & try again
      grid[row][col] = 0;
    }
  }
  // This triggers backtracking
  return false; // This will trigger backtracking
}

// Main function to test the Sudoku solver
int main() {
  int grid[N][N] = {
    {5, 3, 0, 0, 7, 0, 0, 0, 0},
    {6, 0, 0, 1, 9, 5, 0, 0, 0},
    {0, 9, 8, 0, 0, 0, 0, 6, 0},
    {8, 0, 0, 0, 6, 0, 0, 0, 3},
    {4, 0, 0, 8, 0, 3, 0, 0, 1},
    {7, 0, 0, 0, 2, 0, 0, 0, 6},
    {0, 6, 0, 0, 0, 0, 2, 8, 0},
    {0, 0, 0, 4, 1, 9, 0, 0, 5},
    {0, 0, 0, 0, 8, 0, 0, 7, 9}
  };

  if (solveSudoku(grid)) {
    printf("Solution:\\n");
    printGrid(grid);
  } else {
    printf("No solution exists\\n");
  }

  return 0;
}

In this code:

- The isSafe function verifies that placing a number violates no Sudoku rules.

- findUnassignedLocation finds the next empty cell on the grid.

- solveSudoku recursively attempts to solve the puzzle, backtracking when a dead-end is encountered.

This solution demonstrates a classic approach to solving Sudoku, leveraging backtracking and the inherent size relationships within the puzzle's constraints.

More questions