
import numpy as np
from PIL import Image


def 			UpperCamelCase					(    __lowerCamelCase     : np.ndarray				,					__lowerCamelCase     : int				,					__lowerCamelCase     : int    ):
       snake_case       :   List[str]							=      np.array(__lowerCamelCase    )
       if arr.shape[0] != arr.shape[1]:
              raise ValueError("The input array is not a square matrix"    )
       snake_case       :   int							=      0
       snake_case       :   Optional[int]							=      0
       snake_case       :   Tuple							=      0
       snake_case       :   int							=      0

       # compute the shape of the output matrix
       snake_case       :   Optional[int]							=      (arr.shape[0] - size) // stride + 1
       # initialize the output matrix with zeros of shape maxpool_shape
       snake_case       :   Any							=      np.zeros((maxpool_shape, maxpool_shape)    )

       while i < arr.shape[0]:
              if i + size > arr.shape[0]:
                     # if the end of the matrix is reached, break
                     break
              while j < arr.shape[1]:
                     # if the end of the matrix is reached, break
                     if j + size > arr.shape[1]:
                            break
                     # compute the maximum of the pooling matrix
                     snake_case       :   List[str]							=      np.max(arr[i : i + size, j : j + size]    )
                     # shift the pooling matrix by stride of column pixels
                     j += stride
                     mat_j += 1

              # shift the pooling matrix by stride of row pixels
              i += stride
              mat_i += 1

              # reset the column index to 0
              snake_case       :   Optional[Any]							=      0
              snake_case       :   List[Any]							=      0

       return updated_arr


def 			UpperCamelCase					(    __lowerCamelCase     : np.ndarray				,					__lowerCamelCase     : int				,					__lowerCamelCase     : int    ):
       snake_case       :   List[str]							=      np.array(__lowerCamelCase    )
       if arr.shape[0] != arr.shape[1]:
              raise ValueError("The input array is not a square matrix"    )
       snake_case       :   Optional[int]							=      0
       snake_case       :   List[str]							=      0
       snake_case       :   Dict							=      0
       snake_case       :   str							=      0

       # compute the shape of the output matrix
       snake_case       :   List[Any]							=      (arr.shape[0] - size) // stride + 1
       # initialize the output matrix with zeros of shape avgpool_shape
       snake_case       :   int							=      np.zeros((avgpool_shape, avgpool_shape)    )

       while i < arr.shape[0]:
              # if the end of the matrix is reached, break
              if i + size > arr.shape[0]:
                     break
              while j < arr.shape[1]:
                     # if the end of the matrix is reached, break
                     if j + size > arr.shape[1]:
                            break
                     # compute the average of the pooling matrix
                     snake_case       :   Optional[int]							=      int(np.average(arr[i : i + size, j : j + size]    )    )
                     # shift the pooling matrix by stride of column pixels
                     j += stride
                     mat_j += 1

              # shift the pooling matrix by stride of row pixels
              i += stride
              mat_i += 1
              # reset the column index to 0
              snake_case       :   int							=      0
              snake_case       :   Any							=      0

       return updated_arr


# Main Function
if __name__ == "__main__":
   from doctest import testmod

   testmod(name="""avgpooling""", verbose=True)

   # Loading the image
   __lowerCamelCase							=       Image.open("""path_to_image""")

   # Converting the image to numpy array and maxpooling, displaying the result
   # Ensure that the image is a square matrix

   Image.fromarray(maxpooling(np.array(image), size=3, stride=2)).show()

   # Converting the image to numpy array and averagepooling, displaying the result
   # Ensure that the image is a square matrix

   Image.fromarray(avgpooling(np.array(image), size=3, stride=2)).show()







from __future__ import annotations

__lowerCamelCase							=       list[list[int]]

# assigning initial values to the grid
__lowerCamelCase							=       [
    [3, 0, 6, 5, 0, 8, 4, 0, 0],
    [5, 2, 0, 0, 0, 0, 0, 0, 0],
    [0, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 1, 0, 0, 8, 0],
    [9, 0, 0, 8, 6, 3, 0, 0, 5],
    [0, 5, 0, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0],
]

# a grid with no solution
__lowerCamelCase							=       [
    [5, 0, 6, 5, 0, 8, 4, 0, 3],
    [5, 2, 0, 0, 0, 0, 0, 0, 2],
    [1, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 1, 0, 0, 8, 0],
    [9, 0, 0, 8, 6, 3, 0, 0, 5],
    [0, 5, 0, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0],
]


def 			UpperCamelCase					(    __lowerCamelCase     : Matrix				,					__lowerCamelCase     : int				,					__lowerCamelCase     : int				,					__lowerCamelCase     : int    ):
       for i in range(9    ):
              if grid[row][i] == n or grid[i][column] == n:
                     return False

       for i in range(3    ):
              for j in range(3    ):
                     if grid[(row - row % 3) + i][(column - column % 3) + j] == n:
                            return False

       return True


def 			UpperCamelCase					(    __lowerCamelCase     : Matrix    ):
       for i in range(9    ):
              for j in range(9    ):
                     if grid[i][j] == 0:
                            return i, j
       return None


def 			UpperCamelCase					(    __lowerCamelCase     : Matrix    ):
       if location := find_empty_location(__lowerCamelCase    ):
              snake_case				,					snake_case       :   Union[str, Any]							=      location
       else:
              # If the location is ``None``, then the grid is solved.
              return grid

       for digit in range(1				,					10    ):
              if is_safe(__lowerCamelCase				,					__lowerCamelCase				,					__lowerCamelCase				,					__lowerCamelCase    ):
                     snake_case       :   List[Any]							=      digit

                     if sudoku(__lowerCamelCase    ) is not None:
                            return grid

                     snake_case       :   Union[str, Any]							=      0

       return None


def 			UpperCamelCase					(    __lowerCamelCase     : Matrix    ):
       for row in grid:
              for cell in row:
                     print(__lowerCamelCase				,					end=" "    )
              print()


if __name__ == "__main__":
   # make a copy of grid so that you can compare with the unmodified grid
   for example_grid in (initial_grid, no_solution):
      print("""\nExample grid:\n""" + """=""" * 20)
      print_solution(example_grid)
      print("""\nExample grid solution:""")
      __lowerCamelCase							=       sudoku(example_grid)
      if solution is not None:
         print_solution(solution)
      else:
         print("""Cannot find a solution.""")





