Open In App

Program for Sudoku Generator

Last Updated : 15 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an integer k, the task is to generate a 9 x 9 Sudoku grid having k empty cells while following the below set of rules:

  1. In all 9 submatrices 3x3, the elements should be 1-9, without repetition.
  2. In all rows, there should be elements between 1-9, without repetition.
  3. In all columns, there should be elements between 1-9, without repetition.

Naive Approach

  1. Randomly take any number 1-9.
  2. Check if it is safe to put in the cell. (row, column and box)
  3. If safe, place it and increment to the next location and go to step 1.
  4. If not safe, then without increment go to step 1.
  5. Once the matrix is filled, remove k elements randomly to complete the game.

Efficient Approach

We can improve the solution if we understand the pattern in this game. We can observe that all 3 x 3 matrices, which are diagonally present are independent of other 3 x 3 adjacent matrices initially, as others are empty. 

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

We can observe that in above matrix, the diagonal matrices are independent of other empty matrices initially. So if we fill them first, then we will only have to do box check and thus column/row check not required.

Secondly, while we fill rest of the non-diagonal elements, we will not have to use random generator, but we can fill recursively by checking 1 to 9. 

Step by step approach:

  • Fill all the diagonal 3x3 matrices.
  • Fill recursively rest of the non-diagonal matrices. For every cell to be filled, we try all numbers until we find a safe number to be placed.
  • Once matrix is fully filled, remove k elements randomly to complete game.
C++
// C++ program to generate a valid sudoku 
// with k empty cells
#include <bits/stdc++.h>
using namespace std;

// Returns false if given 3x3 block contains num
// Ensure the number is not used in the box
bool unUsedInBox(vector<vector<int>> &grid, int rowStart, int colStart, int num) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (grid[rowStart + i][colStart + j] == num) {
                return false;
            }
        }
    }
    return true;
}

// Fill a 3x3 matrix
// Assign valid random numbers to the 3x3 subgrid
void fillBox(vector<vector<int>> &grid, int row, int col) {
    int num;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            do {
              
                // Generate a random number between 1 and 9
                num = (rand() % 9) + 1;
            } while (!unUsedInBox(grid, row, col, num));
            grid[row + i][col + j] = num;
        }
    }
}

// Check if it's safe to put num in row i
// Ensure num is not already used in the row
bool unUsedInRow(vector<vector<int>> &grid, int i, int num) {
    for (int j = 0; j < 9; j++) {
        if (grid[i][j] == num) {
            return false;
        }
    }
    return true;
}

// Check if it's safe to put num in column j
// Ensure num is not already used in the column
bool unUsedInCol(vector<vector<int>> &grid, int j, int num) {
    for (int i = 0; i < 9; i++) {
        if (grid[i][j] == num) {
            return false;
        }
    }
    return true;
}

// Check if it's safe to put num in the cell (i, j)
// Ensure num is not used in row, column, or box
bool checkIfSafe(vector<vector<int>> &grid, int i, int j, int num) {
    return (unUsedInRow(grid, i, num) && unUsedInCol(grid, j, num) &&
            unUsedInBox(grid, i - i % 3, j - j % 3, num));
}

// Fill the diagonal 3x3 matrices
// The diagonal blocks are filled to simplify the process
void fillDiagonal(vector<vector<int>> &grid) {
    for (int i = 0; i < 9; i = i + 3) {

        // Fill each 3x3 subgrid diagonally
        fillBox(grid, i, i);
    }
}

// Fill remaining blocks in the grid
// Recursively fill the remaining cells with valid numbers
bool fillRemaining(vector<vector<int>> &grid, int i, int j) {
    
    // If we've reached the end of the grid
    if (i == 9) {
        return true;
    }
    
    // Move to next row when current row is finished
    if (j == 9) {
        return fillRemaining(grid, i + 1, 0);
    }
    
    // Skip if cell is already filled
    if (grid[i][j] != 0) {
        return fillRemaining(grid, i, j + 1);
    }
    
    // Try numbers 1-9 in current cell
    for (int num = 1; num <= 9; num++) {
        if (checkIfSafe(grid, i, j, num)) {
            grid[i][j] = num;
            if (fillRemaining(grid, i, j + 1)) {
                return true;
            }
            grid[i][j] = 0; 
        }
    }
    
    return false;
}

// Remove K digits randomly from the grid
// This will create a Sudoku puzzle by removing digits
void removeKDigits(vector<vector<int>> &grid, int k) {
    while (k > 0) {

        // Pick a random cell
        int cellId = rand() % 81;

        // Get the row index
        int i = cellId / 9;

        // Get the column index
        int j = cellId % 9;

        // Remove the digit if the cell is not already empty
        if (grid[i][j] != 0) {

            // Empty the cell
            grid[i][j] = 0;

            // Decrease the count of digits to remove
            k--;
        }
    }
}

// Generate a Sudoku grid with K empty cells
vector<vector<int>> sudokuGenerator(int k) {

    // Initialize an empty 9x9 grid
    vector<vector<int>> grid(9, vector<int>(9, 0));

    // Fill the diagonal 3x3 matrices
    fillDiagonal(grid);

    // Fill the remaining blocks in the grid
    fillRemaining(grid, 0, 0);

    // Remove K digits randomly to create the puzzle
    removeKDigits(grid, k);

    return grid;
}

int main() {

    // Seed the random number generator
    srand(time(0));

    // Set the number of empty cells
    int k = 20;
    vector<vector<int>> sudoku = sudokuGenerator(k);

    // Print the generated Sudoku puzzle
    for (const auto &row : sudoku) {
        for (int cell : row) {
            cout << cell << " ";
        }
        cout << endl;
    }

    return 0;
}
Java
// Java program to generate a valid sudoku 
// with k empty cells
import java.util.Random;

class GfG {

    // Returns false if given 3x3 block contains num
    // Ensure the number is not used in the box
    static boolean unUsedInBox(int[][] grid, int rowStart, int colStart, int num) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (grid[rowStart + i][colStart + j] == num) {
                    return false;
                }
            }
        }
        return true;
    }

    // Fill a 3x3 matrix
    // Assign valid random numbers to the 3x3 subgrid
    static void fillBox(int[][] grid, int row, int col) {
        Random rand = new Random();
        int num;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                do {
                    // Generate a random number between 1 and 9
                    num = rand.nextInt(9) + 1;
                } while (!unUsedInBox(grid, row, col, num));
                grid[row + i][col + j] = num;
            }
        }
    }

    // Check if it's safe to put num in row i
    // Ensure num is not already used in the row
    static boolean unUsedInRow(int[][] grid, int i, int num) {
        for (int j = 0; j < 9; j++) {
            if (grid[i][j] == num) {
                return false;
            }
        }
        return true;
    }

    // Check if it's safe to put num in column j
    // Ensure num is not already used in the column
    static boolean unUsedInCol(int[][] grid, int j, int num) {
        for (int i = 0; i < 9; i++) {
            if (grid[i][j] == num) {
                return false;
            }
        }
        return true;
    }

    // Check if it's safe to put num in the cell (i, j)
    // Ensure num is not used in row, column, or box
    static boolean checkIfSafe(int[][] grid, int i, int j, int num) {
        return (unUsedInRow(grid, i, num) && unUsedInCol(grid, j, num) &&
                unUsedInBox(grid, i - i % 3, j - j % 3, num));
    }

    // Fill the diagonal 3x3 matrices
    // The diagonal blocks are filled to simplify the process
    static void fillDiagonal(int[][] grid) {
        for (int i = 0; i < 9; i = i + 3) {
            // Fill each 3x3 subgrid diagonally
            fillBox(grid, i, i);
        }
    }

    // Fill remaining blocks in the grid
    // Recursively fill the remaining cells with valid numbers
    static boolean fillRemaining(int[][] grid, int i, int j) {
        
        // If we've reached the end of the grid
        if (i == 9) {
            return true;
        }

        // Move to next row when current row is finished
        if (j == 9) {
            return fillRemaining(grid, i + 1, 0);
        }

        // Skip if cell is already filled
        if (grid[i][j] != 0) {
            return fillRemaining(grid, i, j + 1);
        }

        // Try numbers 1-9 in current cell
        for (int num = 1; num <= 9; num++) {
            if (checkIfSafe(grid, i, j, num)) {
                grid[i][j] = num;
                if (fillRemaining(grid, i, j + 1)) {
                    return true;
                }
                grid[i][j] = 0;
            }
        }
        return false;
    }

    // Remove K digits randomly from the grid
    // This will create a Sudoku puzzle by removing digits
    static void removeKDigits(int[][] grid, int k) {
        Random rand = new Random();
        while (k > 0) {
            // Pick a random cell
            int cellId = rand.nextInt(81);

            // Get the row index
            int i = cellId / 9;

            // Get the column index
            int j = cellId % 9;

            // Remove the digit if the cell is not already empty
            if (grid[i][j] != 0) {
                // Empty the cell
                grid[i][j] = 0;

                // Decrease the count of digits to remove
                k--;
            }
        }
    }

    // Generate a Sudoku grid with K empty cells
    static int[][] sudokuGenerator(int k) {
        // Initialize an empty 9x9 grid
        int[][] grid = new int[9][9];

        // Fill the diagonal 3x3 matrices
        fillDiagonal(grid);

        // Fill the remaining blocks in the grid
        fillRemaining(grid, 0, 0);

        // Remove K digits randomly to create the puzzle
        removeKDigits(grid, k);

        return grid;
    }

    public static void main(String[] args) {
        
        // Seed the random number generator
        Random rand = new Random();

        // Set the number of empty cells
        int k = 20;
        int[][] sudoku = sudokuGenerator(k);

        // Print the generated Sudoku puzzle
        for (int[] row : sudoku) {
            for (int cell : row) {
                System.out.print(cell + " ");
            }
            System.out.println();
        }
    }
}
Python
# Python program to generate a valid sudoku 
# with k empty cells

import random

# Returns false if given 3x3 block contains num
# Ensure the number is not used in the box
def unUsedInBox(grid, rowStart, colStart, num):
    for i in range(3):
        for j in range(3):
            if grid[rowStart + i][colStart + j] == num:
                return False
    return True

# Fill a 3x3 matrix
# Assign valid random numbers to the 3x3 subgrid
def fillBox(grid, row, col):
    for i in range(3):
        for j in range(3):
            while True:
                
                # Generate a random number between 1 and 9
                num = random.randint(1, 9)
                if unUsedInBox(grid, row, col, num):
                    break
            grid[row + i][col + j] = num

# Check if it's safe to put num in row i
# Ensure num is not already used in the row
def unUsedInRow(grid, i, num):
    return num not in grid[i]

# Check if it's safe to put num in column j
# Ensure num is not already used in the column
def unUsedInCol(grid, j, num):
    for i in range(9):
        if grid[i][j] == num:
            return False
    return True

# Check if it's safe to put num in the cell (i, j)
# Ensure num is not used in row, column, or box
def checkIfSafe(grid, i, j, num):
    return (unUsedInRow(grid, i, num) and 
            unUsedInCol(grid, j, num) and 
            unUsedInBox(grid, i - i % 3, j - j % 3, num))

# Fill the diagonal 3x3 matrices
# The diagonal blocks are filled to simplify the process
def fillDiagonal(grid):
    for i in range(0, 9, 3):
        
        # Fill each 3x3 subgrid diagonally
        fillBox(grid, i, i)

# Fill remaining blocks in the grid
# Recursively fill the remaining cells with valid numbers
def fillRemaining(grid, i, j):
    
    # If we've reached the end of the grid
    if i == 9:
        return True
    
    # Move to next row when current row is finished
    if j == 9:
        return fillRemaining(grid, i + 1, 0)
    
    # Skip if cell is already filled
    if grid[i][j] != 0:
        return fillRemaining(grid, i, j + 1)
    
    # Try numbers 1-9 in current cell
    for num in range(1, 10):
        if checkIfSafe(grid, i, j, num):
            grid[i][j] = num
            if fillRemaining(grid, i, j + 1):
                return True
            grid[i][j] = 0 
    
    return False

# Remove K digits randomly from the grid
# This will create a Sudoku puzzle by removing digits
def removeKDigits(grid, k):
    while k > 0:
        
        # Pick a random cell
        cellId = random.randint(0, 80)

        # Get the row index
        i = cellId // 9

        # Get the column index
        j = cellId % 9

        # Remove the digit if the cell is not already empty
        if grid[i][j] != 0:
            # Empty the cell
            grid[i][j] = 0
            # Decrease the count of digits to remove
            k -= 1

# Generate a Sudoku grid with K empty cells
def sudokuGenerator(k):
    
    # Initialize an empty 9x9 grid
    grid = [[0] * 9 for _ in range(9)]

    # Fill the diagonal 3x3 matrices
    fillDiagonal(grid)

    # Fill the remaining blocks in the grid
    fillRemaining(grid, 0, 0)

    # Remove K digits randomly to create the puzzle
    removeKDigits(grid, k)

    return grid

if __name__ == "__main__":
    
    # Seed the random number generator
    random.seed()

    # Set the number of empty cells
    k = 20
    sudoku = sudokuGenerator(k)

    # Print the generated Sudoku puzzle
    for row in sudoku:
        print(" ".join(map(str, row)))
C#
// C# program to generate a valid sudoku 
// with k empty cells
using System;

class GfG {
    
    // Returns false if given 3x3 block contains num
    // Ensure the number is not used in the box
    static bool unUsedInBox(int[,] grid, int rowStart, int colStart, int num) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (grid[rowStart + i, colStart + j] == num) {
                    return false;
                }
            }
        }
        return true;
    }

    // Fill a 3x3 matrix
    // Assign valid random numbers to the 3x3 subgrid
    static void fillBox(int[,] grid, int row, int col) {
        Random rand = new Random();
        int num;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                do {
                    // Generate a random number between 1 and 9
                    num = rand.Next(1, 10);
                } while (!unUsedInBox(grid, row, col, num));
                grid[row + i, col + j] = num;
            }
        }
    }

    // Check if it's safe to put num in row i
    // Ensure num is not already used in the row
    static bool unUsedInRow(int[,] grid, int i, int num) {
        for (int j = 0; j < 9; j++) {
            if (grid[i, j] == num) {
                return false;
            }
        }
        return true;
    }

    // Check if it's safe to put num in column j
    // Ensure num is not already used in the column
    static bool unUsedInCol(int[,] grid, int j, int num) {
        for (int i = 0; i < 9; i++) {
            if (grid[i, j] == num) {
                return false;
            }
        }
        return true;
    }

    // Check if it's safe to put num in the cell (i, j)
    // Ensure num is not used in row, column, or box
    static bool checkIfSafe(int[,] grid, int i, int j, int num) {
        return (unUsedInRow(grid, i, num) && unUsedInCol(grid, j, num) &&
                unUsedInBox(grid, i - i % 3, j - j % 3, num));
    }

    // Fill the diagonal 3x3 matrices
    // The diagonal blocks are filled to simplify the process
    static void fillDiagonal(int[,] grid) {
        for (int i = 0; i < 9; i += 3) {
            // Fill each 3x3 subgrid diagonally
            fillBox(grid, i, i);
        }
    }

    // Fill remaining blocks in the grid
    // Recursively fill the remaining cells with valid numbers
    static bool fillRemaining(int[,] grid, int i, int j) {
        if (i == 9) {
            return true;
        }
        if (j == 9) {
            return fillRemaining(grid, i + 1, 0);
        }
        if (grid[i, j] != 0) {
            return fillRemaining(grid, i, j + 1);
        }
        for (int num = 1; num <= 9; num++) {
            if (checkIfSafe(grid, i, j, num)) {
                grid[i, j] = num;
                if (fillRemaining(grid, i, j + 1)) {
                    return true;
                }
                grid[i, j] = 0;
            }
        }
        return false;
    }

    // Remove K digits randomly from the grid
    // This will create a Sudoku puzzle by removing digits
    static void removeKDigits(int[,] grid, int k) {
        Random rand = new Random();
        while (k > 0) {
            int cellId = rand.Next(81);
            int i = cellId / 9;
            int j = cellId % 9;
            if (grid[i, j] != 0) {
                grid[i, j] = 0;
                k--;
            }
        }
    }

    // Generate a Sudoku grid with K empty cells
    static int[,] sudokuGenerator(int k) {
        int[,] grid = new int[9, 9];
        fillDiagonal(grid);
        fillRemaining(grid, 0, 0);
        removeKDigits(grid, k);
        return grid;
    }

    static void Main() {
        
        int k = 20;
        int[,] sudoku = sudokuGenerator(k);

        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                Console.Write(sudoku[i, j] + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// JavaScript program to generate a valid sudoku 
// with k empty cells

// Returns false if given 3x3 block contains num
// Ensure the number is not used in the box
function unUsedInBox(grid, rowStart, colStart, num) {
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            if (grid[rowStart + i][colStart + j] === num) {
                return false;
            }
        }
    }
    return true;
}

// Fill a 3x3 matrix
// Assign valid random numbers to the 3x3 subgrid
function fillBox(grid, row, col) {
    let num;
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            do {
                // Generate a random number between 1 and 9
                num = Math.floor(Math.random() * 9) + 1;
            } while (!unUsedInBox(grid, row, col, num));
            grid[row + i][col + j] = num;
        }
    }
}

// Check if it's safe to put num in row i
// Ensure num is not already used in the row
function unUsedInRow(grid, i, num) {
    for (let j = 0; j < 9; j++) {
        if (grid[i][j] === num) {
            return false;
        }
    }
    return true;
}

// Check if it's safe to put num in column j
// Ensure num is not already used in the column
function unUsedInCol(grid, j, num) {
    for (let i = 0; i < 9; i++) {
        if (grid[i][j] === num) {
            return false;
        }
    }
    return true;
}

// Check if it's safe to put num in the cell (i, j)
// Ensure num is not used in row, column, or box
function checkIfSafe(grid, i, j, num) {
    return unUsedInRow(grid, i, num) && unUsedInCol(grid, j, num) &&
           unUsedInBox(grid, i - (i % 3), j - (j % 3), num);
}

// Fill the diagonal 3x3 matrices
// The diagonal blocks are filled to simplify the process
function fillDiagonal(grid) {
    
    for (let i = 0; i < 9; i += 3) {
        
        // Fill each 3x3 subgrid diagonally
        fillBox(grid, i, i);
    }
}

// Fill remaining blocks in the grid
// Recursively fill the remaining cells with valid numbers
function fillRemaining(grid, i, j) {
    
    // If we've reached the end of the grid
    if (i === 9) {
        return true;
    }

    // Move to next row when current row is finished
    if (j === 9) {
        return fillRemaining(grid, i + 1, 0);
    }

    // Skip if cell is already filled
    if (grid[i][j] !== 0) {
        return fillRemaining(grid, i, j + 1);
    }

    // Try numbers 1-9 in current cell
    for (let num = 1; num <= 9; num++) {
        if (checkIfSafe(grid, i, j, num)) {
            grid[i][j] = num;
            if (fillRemaining(grid, i, j + 1)) {
                return true;
            }
            grid[i][j] = 0;
        }
    }

    return false;
}

// Remove K digits randomly from the grid
// This will create a Sudoku puzzle by removing digits
function removeKDigits(grid, k) {
    while (k > 0) {
        
        // Pick a random cell
        let cellId = Math.floor(Math.random() * 81);

        // Get the row index
        let i = Math.floor(cellId / 9);

        // Get the column index
        let j = cellId % 9;

        // Remove the digit if the cell is not already empty
        if (grid[i][j] !== 0) {
            // Empty the cell
            grid[i][j] = 0;

            // Decrease the count of digits to remove
            k--;
        }
    }
}

// Generate a Sudoku grid with K empty cells
function sudokuGenerator(k) {
    
    // Initialize an empty 9x9 grid
    let grid = new Array(9).fill(0).map(() => new Array(9).fill(0));

    // Fill the diagonal 3x3 matrices
    fillDiagonal(grid);

    // Fill the remaining blocks in the grid
    fillRemaining(grid, 0, 0);

    // Remove K digits randomly to create the puzzle
    removeKDigits(grid, k);

    return grid;
}

let k = 20;
let sudoku = sudokuGenerator(k);

sudoku.forEach(row => console.log(row.join(" ")));

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

Time Complexity: O(k) 
Auxiliary Space: O(1)


Article Tags :
Practice Tags :

Similar Reads