input: Write a function to solve any Sudoku puzzle given a 9x9 grid where empty cells are represented by the number 0. Implement the function solve_sudoku(board) that uses backtracking to fill the board with valid numbers and returns a solved Sudoku grid. If no solution exists, print "No solution". 
  
  def solve_sudoku(board): 
    
      # Utility function to find vacant cells 
      # Returns a boolean     
      def find_vacant_cell(board, l): 
          for row in range(9): 
              for col in range(9): 
                  if board[row][col] == 0: 
                      l[0] = row 
                      l[1] = col 
                      return True
          return False
    
      # Utility function to check if a number  
      # is not currently placed in a particular  
      # row, column and block 
      def is_safe(board, row, col, num): 
    
          # Check if 'num' is not already placed  
          # in current row, current column  
          # and current 3x3 box 
          for i in range(9): 
    
              # Check the rows
              if(board[row][i] == num): 
                  return False
    
              # Check the columns 
              if(board[i][col] == num): 
                  return False
    
              # Check the 3x3 boxes 
              if(board[(row//3)*3 + i//3][(col//3)*3 + i%3] == num): 
                  return False
    
          return True
    
      # Solve the sudoku 
      def solve(board): 
          # 'l' is a list variable that keeps 
          # the record of row and col in 
          # find_vacant_cell function 
          l = [0, 0] 
    
          # If there is no unassigned location, 
          # we are done 
          if (not find_vacant_cell(board, l)): 
              return True
    
          # Assigning the list values
          row = l[0] 
          col = l[1] 
    
          # consider digits 1 to 9 
          for num in range(1, 10): 
    
              # if it is a safe position
              if (is_safe(board, row, col, num)): 
    
                  # make tentative assignment 
                  board[row][col] = num 
    
                  # return if succcess
                  if (solve(board)): 
                      return True
    
                  # failure, unmake and try again 
                  board[row][col] = 0
    
          # trigger backtracking 
          return False
    
      #Driver Program 
      if (solve(board)): 
          return board
      else: 
          print("No solution")
  
  assert solve_sudoku([
      [7,8,0,4,0,0,1,2,0],
      [6,0,0,0,7,5,0,0,9],
      [0,0,0,6,0,1,0,7,8],
      [0,0,7,0,4,0,2,6,0],
      [0,0,1,0,5,0,9,3,0],
      [9,0,4,0,6,0,0,0,5],
      [0,7,0,3,0,0,0,1,2],
      [1,2,0,0,0,7,4,0,0],
      [0,4,9,2,0,6,0,0,7]
  ]) == [
      [7,8,5,4,3,9,1,2,6],
      [6,1,2,8,7,5,3,4,9],
      [4,9,3,6,2,1,5,7,8],
      [8,5,7,9,4,3,2,6,1],
      [2,6,1,7,5,8,9,3,4],
      [9,3,4,1,6,2,7,8,5],
      [5,7,8,3,9,4,6,1,2],
      [1,2,6,5,8,7,4,9,3],
      [3,4,9,2,1,6,8,5,7]
  ]
output: def solve_sudoku(board): 
    
      def find_vacant_cell(board, l): 
          for row in range(9): 
              for col in range(9): 
                  if board[row][col] == 0: 
                      l[0] = row 
                      l[1] = col 
                      return True
          return False
    
      def is_safe(board, row, col, num): 
          for i in range(9): 
              if(board[row][i] == num): 
                  return False
              if(board[i][col] == num): 
                  return False
              if(board[(row//3)*3 + i//3][(col//3)*3 + i%3] == num): 
                  return False
          return True
    
      def solve(board): 
          l = [0, 0] 
          if (not find_vacant_cell(board, l)): 
              return True
          row = l[0] 
          col = l[1] 
          for num in range(1, 10): 
              if (is_safe(board, row, col, num)): 
                  board[row][col] = num 
                  if (solve(board)): 
                      return True
                  board[row][col] = 0
          return False
    
      if (solve(board)): 
          return board
      else: 
          print("No solution")