Sudoku Solver Project (code) in Python

← Back to Projects

Sudoku Solver in Python

About the project: This is a project for a Sudoku Solver in Python. This script will solve any valid Sudoku puzzle using a classic backtracking algorithm, which is a powerful technique for solving this type of problem.

The project is a single, self-contained Python file. It includes a sample puzzle and functions to solve it and display the results neatly on the console.

The solve_sudoku function uses a backtracking algorithm. This is a powerful technique that tries to build a solution incrementally. If a path leads to a dead end (a number can't be placed), the algorithm "backtracks" to the previous choice and tries a different option until it finds a valid path to the solution.


Project Level: Intermediate

You can directly copy the below snippet code with the help of green copy button, paste it and run it in any Python editor you have.

Steps: Follow these steps

Step 1: Copy below code using green 'copy' button.

Step 2: Paste the code on your chosen editor.

Step 3: Save the code with filename and .py extention.

Step 4: Run (Press F5 if using python IDLE)



# sudoku_solver.py

def print_board(board):
    """
    Prints the Sudoku board in a clean, readable format.
    Adds lines to separate the 3x3 sub-grids.
    """
    for i, row in enumerate(board):
        if i % 3 == 0 and i != 0:
            print("- - - - - - - - - - - -")
        for j, val in enumerate(row):
            if j % 3 == 0 and j != 0:
                print(" | ", end="")
            if j == 8:
                print(val)
            else:
                print(str(val) + " ", end="")

def find_empty_location(board):
    """
    Finds the next empty location (a cell with value 0) on the board.
    
    Args:
        board (list of lists): The 9x9 Sudoku board.
    
    Returns:
        tuple or None: A tuple (row, col) of the empty location, or None if no empty cells exist.
    """
    for row in range(9):
        for col in range(9):
            if board[row][col] == 0:
                return (row, col)
    return None

def is_valid_move(board, row, col, num):
    """
    Checks if it's safe to place a number at a given location.
    
    Args:
        board (list of lists): The 9x9 Sudoku board.
        row (int): The row index.
        col (int): The column index.
        num (int): The number to check (1-9).
        
    Returns:
        bool: True if the move is valid, False otherwise.
    """
    # Check if the number is already in the row
    if num in board[row]:
        return False
        
    # Check if the number is already in the column
    for r in range(9):
        if board[r][col] == num:
            return False
            
    # Check if the number is in the 3x3 sub-grid
    start_row = row - row % 3
    start_col = col - col % 3
    for r in range(start_row, start_row + 3):
        for c in range(start_col, start_col + 3):
            if board[r][c] == num:
                return False
                
    return True

def solve_sudoku(board):
    """
    The main Sudoku solver function using a backtracking algorithm.
    
    Args:
        board (list of lists): The 9x9 Sudoku board.
    
    Returns:
        bool: True if a solution is found, False if the puzzle is unsolvable.
    """
    # Find the next empty cell
    find = find_empty_location(board)
    
    # Base case: If no empty cells, the puzzle is solved.
    if not find:
        return True
    else:
        row, col = find
        
    # Recursive case: Try placing numbers 1-9 in the empty cell.
    for num in range(1, 10):
        if is_valid_move(board, row, col, num):
            # If the number is valid, place it
            board[row][col] = num
            
            # Recursively call the solver. If it finds a solution, we're done.
            if solve_sudoku(board):
                return True
                
            # If the recursive call fails, backtrack and reset the cell to 0
            board[row][col] = 0
            
    # If no number from 1-9 works, this path is a dead end. Return False to backtrack.
    return False

# Example usage
if __name__ == "__main__":
    # A sample Sudoku puzzle (0 represents an empty cell)
    # This board is from a real Sudoku puzzle.
    example_board = [
        [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]
    ]

    print("--- Unsolved Sudoku Board ---")
    print_board(example_board)
    print("\nAttempting to solve...\n")

    if solve_sudoku(example_board):
        print("--- Solved Sudoku Board ---")
        print_board(example_board)
    else:
        print("No solution exists for this Sudoku puzzle.")




← Back to Projects