input: Write a function to solve a Sudoku puzzle given a 9x9 board as a 2D list. The function should return the solved board if there is a solution, and print "No solution" if there is no solution. The board is represented by numbers where 0 indicates an empty cell.
  
  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")
          return None
  
  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]
  ]) is not None
  assert solve_sudoku([
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0, 0]
  ]) is not None
  assert solve_sudoku([
      [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]
  ]) is not None
  assert solve_sudoku([
      [1, 2, 3, 4, 5, 6, 7, 8, 9],
      [4, 5, 6, 7, 8, 9, 1, 2, 3],
      [7, 8, 9, 1, 2, 3, 4, 5, 6],
      [2, 3, 4, 5, 6, 7, 8, 9, 1],
      [5, 6, 7, 8, 9, 1, 2, 3, 4],
      [8, 9, 1, 2, 3, 4, 5, 6, 7],
      [3, 4, 5, 6, 7, 8, 9, 1, 2],
      [6, 7, 8, 9, 1, 2, 3, 4, 5],
      [9, 1, 2, 3, 4, 5, 6, 7, 8]
  ]) is not None
output: 
  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")
          return None
  