Sudoku Solving algorithms



What is a Sudoku?

Sudoku is a logical puzzle where a partially filled 9x9 grid needs to be filled with numbers from 1 to 9, ensuring that each row and column contains all digits from 1 to 9 uniquely. Also, each 3x3 sub-grid (also called a box) contains all digits from 1 to 9 uniquely. There are several algorithms that solve this puzzle efficiently. In this tutorial, we are going to learn how to solve a sudoku puzzle using backtracking.

Backtracking Approach to solve Sudoku

Suppose the given 9x9 matrix represents a sudoku grid. In it, the blank spaces are denoted by 0. The final output matrix (Sudoku grid) will be filled with numbers. If the solution does not exist, it will return false. The figure below illustrates the problem and solution of the given sudoku −

Sudoku Solving

In the naive method to solve sudoku problem, the algorithm generates all possible combinations of numbers from 1 to 9 to fill the empty cell. After assigning a number to each cell one by one, check whether the assignment is valid or not. This way of solving sudoku problems is very lengthy and time consuming.

Steps

Follow the below steps to solve sudoku problem using the backtracking approach −

  • First, identify empty cells which is defined by 0.

  • If an empty cell is found, check if it is valid to put a number in that cell by checking whether the number already exists in the same row, column, or 3x3 sub-grid.

  • If it is valid to place a number in the cell, the number is assigned to the cell. Otherwise, backtrack and assign 0 again.

Example

In this example, we are illustrating how to solve the Sudoku problem in various programming languages.

#include 
#define N 9
int grid[N][N] = { 
    { 3, 1, 0, 5, 7, 8, 4, 0, 2 },
    { 0, 2, 9, 0, 3, 0, 0, 0, 8 },
    { 4, 0, 0, 6, 2, 9, 0, 3, 1 },
    { 2, 0, 3, 0, 1, 0, 0, 8, 0 },
    { 0, 7, 0, 8, 6, 3, 0, 0, 5 },
    { 8, 0, 1, 0, 9, 0, 6, 0, 0 },
    { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
    { 6, 9, 2, 0, 5, 0, 0, 7, 4 },
    { 7, 0, 0, 2, 0, 6, 3, 0, 0 }
};
//check whether num is present in col or not
int isPresentInCol(int col, int num) {    
   for (int row = 0; row < N; row++)
      if (grid[row][col] == num)
         return 1;
   return 0;
}
//check whether num is present in row or not
int isPresentInRow(int row, int num) {    
   for (int col = 0; col < N; col++)
      if (grid[row][col] == num)
         return 1;
   return 0;
}
//check whether num is present in 3x3 box or not
int isPresentInBox(int boxStartRow, int boxStartCol, int num) {    
   for (int row = 0; row < 3; row++)
      for (int col = 0; col < 3; col++)
         if (grid[row+boxStartRow][col+boxStartCol] == num)
            return 1;
   return 0;
}
//print the sudoku grid after solving
void sudokuGrid() {   
   for (int row = 0; row < N; row++) {
      for (int col = 0; col < N; col++) {
         if(col == 3 || col == 6)
            printf(" | ");
         printf("%d ", grid[row][col]);
      }
      if(row == 2 || row == 5) {
         printf("\n");
         for(int i = 0; i
    
#include 
#define N 9
using namespace std;
int grid[N][N] = { 
    { 3, 1, 0, 5, 7, 8, 4, 0, 2 },
    { 0, 2, 9, 0, 3, 0, 0, 0, 8 },
    { 4, 0, 0, 6, 2, 9, 0, 3, 1 },
    { 2, 0, 3, 0, 1, 0, 0, 8, 0 },
    { 0, 7, 0, 8, 6, 3, 0, 0, 5 },
    { 8, 0, 1, 0, 9, 0, 6, 0, 0 },
    { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
    { 6, 9, 2, 0, 5, 0, 0, 7, 4 },
    { 7, 0, 0, 2, 0, 6, 3, 0, 0 }
};
//check whether num is present in col or not
bool isPresentInCol(int col, int num) {    
   for (int row = 0; row < N; row++)
      if (grid[row][col] == num)
         return true;
   return false;
}
//check whether num is present in row or not
bool isPresentInRow(int row, int num) {    
   for (int col = 0; col < N; col++)
      if (grid[row][col] == num)
         return true;
   return false;
}
//check whether num is present in 3x3 box or not
bool isPresentInBox(int boxStartRow, int boxStartCol, int num) {    
   for (int row = 0; row < 3; row++)
      for (int col = 0; col < 3; col++)
         if (grid[row+boxStartRow][col+boxStartCol] == num)
            return true;
   return false;
}
 //print the sudoku grid after solving
void sudokuGrid() {   
   for (int row = 0; row < N; row++) {
      for (int col = 0; col < N; col++) {
         if(col == 3 || col == 6)
            cout << " | ";
         cout << grid[row][col] <<" ";
      }
      if(row == 2 || row == 5) {
         cout << endl;
         for(int i = 0; i
    
public class Main {
    static int N = 9;
    static int[][] grid = { 
        { 3, 1, 0, 5, 7, 8, 4, 0, 2 },
        { 0, 2, 9, 0, 3, 0, 0, 0, 8 },
        { 4, 0, 0, 6, 2, 9, 0, 3, 1 },
        { 2, 0, 3, 0, 1, 0, 0, 8, 0 },
        { 0, 7, 0, 8, 6, 3, 0, 0, 5 },
        { 8, 0, 1, 0, 9, 0, 6, 0, 0 },
        { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
        { 6, 9, 2, 0, 5, 0, 0, 7, 4 },
        { 7, 0, 0, 2, 0, 6, 3, 0, 0 }
    };
    //check whether num is present in col or not
    static boolean isPresentInCol(int col, int num) {    
       for (int row = 0; row < N; row++)
          if (grid[row][col] == num)
             return true;
       return false;
    }
    //check whether num is present in row or not
    static boolean isPresentInRow(int row, int num) {    
       for (int col = 0; col < N; col++)
          if (grid[row][col] == num)
             return true;
       return false;
    }
    //check whether num is present in 3x3 box or not
    static boolean isPresentInBox(int boxStartRow, int boxStartCol, int num) {    
       for (int row = 0; row < 3; row++)
          for (int col = 0; col < 3; col++)
             if (grid[row+boxStartRow][col+boxStartCol] == num)
                return true;
       return false;
    }
    //print the sudoku grid after solving
    static void sudokuGrid() {   
       for (int row = 0; row < N; row++) {
          for (int col = 0; col < N; col++) {
             if(col == 3 || col == 6)
                System.out.print(" | ");
             System.out.print(grid[row][col] + " ");
          }
          if(row == 2 || row == 5) {
             System.out.println();
             for(int i = 0; i
    
# Define the size of the grid
N = 9

# Initialize the grid
grid = [
    [3, 1, 0, 5, 7, 8, 4, 0, 2],
    [0, 2, 9, 0, 3, 0, 0, 0, 8],
    [4, 0, 0, 6, 2, 9, 0, 3, 1],
    [2, 0, 3, 0, 1, 0, 0, 8, 0],
    [0, 7, 0, 8, 6, 3, 0, 0, 5],
    [8, 0, 1, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [6, 9, 2, 0, 5, 0, 0, 7, 4],
    [7, 0, 0, 2, 0, 6, 3, 0, 0]
]
# Check whether num is present in col or not
def isPresentInCol(col, num):
    for row in range(N):
        if grid[row][col] == num:
            return True
    return False

# Check whether num is present in row or not
def isPresentInRow(row, num):
    for col in range(N):
        if grid[row][col] == num:
            return True
    return False

# Check whether num is present in 3x3 box or not
def isPresentInBox(boxStartRow, boxStartCol, num):
    for row in range(3):
        for col in range(3):
            if grid[row+boxStartRow][col+boxStartCol] == num:
                return True
    return False

# Print the sudoku grid after solving
def sudokuGrid():
    for row in range(N):
        for col in range(N):
            if col == 3 or col == 6:
                print(" | ", end="")
            print(grid[row][col], end=" ")
        if row == 2 or row == 5:
            print("\n" + "---"*N)
        print()

# Get empty location and update row and column
def findEmptyPlace():
    for row in range(N):
        for col in range(N):
            # Marked with 0 is empty
            if grid[row][col] == 0:
                return row, col
    return None, None

def isValidPlace(row, col, num):
    # When item not found in col, row and current 3x3 box
    return not isPresentInRow(row, num) and not isPresentInCol(col, num) and not isPresentInBox(row - row%3, col - col%3, num)

def solveSudoku():
    row, col = findEmptyPlace()

    # When all places are filled
    if row is None and col is None:
        return True

    # Valid numbers are 1 - 9
    for num in range(1, 10):
        # Check validation, if yes, put the number in the grid
        if isValidPlace(row, col, num):
            grid[row][col] = num

            # Recursively go for other rooms in the grid
            if solveSudoku():
                return True

            # Turn to unassigned space when conditions are not satisfied
            grid[row][col] = 0

    return False

if __name__ == "__main__":
    if solveSudoku():
        sudokuGrid()
    else:
        print("Can't get a solution")

Output

3 1 6  | 5 7 8  | 4 9 2 
5 2 9  | 1 3 4  | 7 6 8 
4 8 7  | 6 2 9  | 5 3 1 
---------------------------
2 6 3  | 4 1 5  | 9 8 7 
9 7 4  | 8 6 3  | 1 2 5 
8 5 1  | 7 9 2  | 6 4 3 
---------------------------
1 3 8  | 9 4 7  | 2 5 6 
6 9 2  | 3 5 1  | 8 7 4 
7 4 5  | 2 8 6  | 3 1 9 
Advertisements