


from __future__ import annotations

snake_case				:    Any       				=     list[list[int]]

# assigning initial values to the grid
snake_case				:    Matrix       				=     [
    [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
snake_case				:    Matrix       				=     [
    [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 				__lowerCamelCase						( UpperCAmelCase_						:		Matrix ,  UpperCAmelCase_						:		int ,  UpperCAmelCase_						:		int ,  UpperCAmelCase_						:		int						):




      """simple docstring"""





      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 				__lowerCamelCase						( UpperCAmelCase_						:		Matrix						):




      """simple docstring"""





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




      """simple docstring"""





      if location := find_empty_location(UpperCAmelCase_						):
            a							,				a						:Dict 							=       location
      else:
            # If the location is ``None``, then the grid is solved.
            return grid

      for digit in range(1 ,  10						):
            if is_safe(UpperCAmelCase_ ,  UpperCAmelCase_ ,  UpperCAmelCase_ ,  UpperCAmelCase_						):
                  a						:Optional[Any] 							=       digit

                  if sudoku(UpperCAmelCase_						) is not None:
                        return grid

                  a						:Optional[int] 							=       0

      return None
def 				__lowerCamelCase						( UpperCAmelCase_						:		Matrix						):




      """simple docstring"""





      for row in grid:
            for cell in row:
                  print(UpperCAmelCase_ ,  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:''')
          snake_case				:    Optional[Any]       				=     sudoku(example_grid)
          if solution is not None:
               print_solution(solution)
          else:
               print('''Cannot find a solution.''')









import string

import numpy
def 				__lowerCamelCase						( UpperCAmelCase_						:		int ,  UpperCAmelCase_						:		int						):




      """simple docstring"""





      return b if a == 0 else greatest_common_divisor(b % a ,  UpperCAmelCase_						)







class 		_snake_case  :
 SCREAMING_SNAKE_CASE__      =       string.ascii_uppercase + string.digits
 # This cipher takes alphanumerics into account
 # i.e. a total of 36 characters

 # take x and return x % len(key_string)
 SCREAMING_SNAKE_CASE__      =       numpy.vectorize(lambda _snake_case							: x % 36							)

 SCREAMING_SNAKE_CASE__      =       numpy.vectorize(_snake_case							)




 def __init__(		self					,  _lowerCamelCase    ):
       a						:List[Any] 							=       self.modulus(_lowerCamelCase    )  # mod36 calc's on the encrypt key
       self.check_determinant()  # validate the determinant of the encryption key
       a						:int 							=       encrypt_key.shape[0]




 def        SCREAMING_SNAKE_CASE__				(		self					,  _lowerCamelCase    ):
       return self.key_string.index(_lowerCamelCase    )




 def        SCREAMING_SNAKE_CASE__				(		self					,  _lowerCamelCase    ):
       return self.key_string[round(_lowerCamelCase    )]




 def        SCREAMING_SNAKE_CASE__				(		self    ):
       a						:str 							=       round(numpy.linalg.det(self.encrypt_key    )    )

       if det < 0:
             a						:Any 							=       det % len(self.key_string    )

       a						:Dict 							=       len(self.key_string    )
       if greatest_common_divisor(_lowerCamelCase					,  len(self.key_string    )    ) != 1:
             a						:int 							=       (
                 F'''determinant modular {req_l} of encryption key({det}) '''
                 F'''is not co prime w.r.t {req_l}.\nTry another key.'''
             )
             raise ValueError(_lowerCamelCase    )




 def        SCREAMING_SNAKE_CASE__				(		self					,  _lowerCamelCase    ):
       a						:Optional[Any] 							=       [char for char in text.upper() if char in self.key_string]

       a						:List[str] 							=       chars[-1]
       while len(_lowerCamelCase    ) % self.break_key != 0:
             chars.append(_lowerCamelCase    )

       return "".join(_lowerCamelCase    )




 def        SCREAMING_SNAKE_CASE__				(		self					,  _lowerCamelCase    ):
       a						:Dict 							=       self.process_text(text.upper()    )
       a						:List[str] 							=       ''''''

       for i in range(0					,  len(_lowerCamelCase    ) - self.break_key + 1					,  self.break_key    ):
             a						:int 							=       text[i : i + self.break_key]
             a						:Optional[int] 							=       [self.replace_letters(_lowerCamelCase    ) for char in batch]
             a						:Union[str, Any] 							=       numpy.array([vec]    ).T
             a						:str 							=       self.modulus(self.encrypt_key.dot(_lowerCamelCase    )    ).T.tolist()[
                 0
             ]
             a						:List[Any] 							=       ''''''.join(
                 self.replace_digits(_lowerCamelCase    ) for num in batch_encrypted    )
             encrypted += encrypted_batch

       return encrypted




 def        SCREAMING_SNAKE_CASE__				(		self    ):
       a						:List[Any] 							=       round(numpy.linalg.det(self.encrypt_key    )    )

       if det < 0:
             a						:int 							=       det % len(self.key_string    )
       a						:Tuple 							=       None
       for i in range(len(self.key_string    )    ):
             if (det * i) % len(self.key_string    ) == 1:
                   a						:Tuple 							=       i
                   break

       a						:List[str] 							=       (
           det_inv
           * numpy.linalg.det(self.encrypt_key    )
           * numpy.linalg.inv(self.encrypt_key    )
       )

       return self.to_int(self.modulus(_lowerCamelCase    )    )




 def        SCREAMING_SNAKE_CASE__				(		self					,  _lowerCamelCase    ):
       a						:List[Any] 							=       self.make_decrypt_key()
       a						:str 							=       self.process_text(text.upper()    )
       a						:List[Any] 							=       ''''''

       for i in range(0					,  len(_lowerCamelCase    ) - self.break_key + 1					,  self.break_key    ):
             a						:Optional[Any] 							=       text[i : i + self.break_key]
             a						:List[Any] 							=       [self.replace_letters(_lowerCamelCase    ) for char in batch]
             a						:str 							=       numpy.array([vec]    ).T
             a						:Dict 							=       self.modulus(decrypt_key.dot(_lowerCamelCase    )    ).T.tolist()[0]
             a						:List[Any] 							=       ''''''.join(
                 self.replace_digits(_lowerCamelCase    ) for num in batch_decrypted    )
             decrypted += decrypted_batch

       return decrypted







def 				__lowerCamelCase						( ):




      """simple docstring"""





      a						:Tuple 							=       int(input('''Enter the order of the encryption key: '''						)						)
      a						:Dict 							=       []

      print('''Enter each row of the encryption key with space separated integers'''						)
      for _ in range(UpperCAmelCase_						):
            a						:List[str] 							=       [int(UpperCAmelCase_						) for x in input().split()]
            hill_matrix.append(UpperCAmelCase_						)

      a						:Any 							=       HillCipher(numpy.array(UpperCAmelCase_						)						)

      print('''Would you like to encrypt or decrypt some text? (1 or 2)'''						)
      a						:Any 							=       input('''\n1. Encrypt\n2. Decrypt\n'''						)
      if option == "1":
            a						:str 							=       input('''What text would you like to encrypt?: '''						)
            print('''Your encrypted text is:'''						)
            print(hc.encrypt(UpperCAmelCase_						)						)
      elif option == "2":
            a						:Dict 							=       input('''What text would you like to decrypt?: '''						)
            print('''Your decrypted text is:'''						)
            print(hc.decrypt(UpperCAmelCase_						)						)


if __name__ == "__main__":
     import doctest

     doctest.testmod()

     main()





