
import string

import numpy


def 							a__					(							snake_case       ,			snake_case							):





  """simple docstring"""
  return b if a == 0 else greatest_common_divisor(b % a       ,			snake_case							)





class     __UpperCamelCase :






     """simple docstring"""







     lowerCAmelCase_							   =			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)
     lowerCAmelCase_							   =			numpy.vectorize(lambda lowerCAmelCase__       : x % 36       )

     lowerCAmelCase_							   =			numpy.vectorize(lowerCAmelCase__       )



     def __init__(				self							:							List[Any]     ,						_A							:							numpy.ndarray ):







       """simple docstring"""




       __SCREAMING_SNAKE_CASE      :	List[Any]					=		self.modulus(_A )  # mod36 calc's on the encrypt key
       self.check_determinant()  # validate the determinant of the encryption key
       __SCREAMING_SNAKE_CASE      :	str					=		encrypt_key.shape[0]



     def  UpperCAmelCase__							(				self							:							Optional[Any]     ,						_A							:							str ):







       """simple docstring"""




       return self.key_string.index(_A )



     def  UpperCAmelCase__							(				self							:							Union[str, Any]     ,						_A							:							int ):







       """simple docstring"""




       return self.key_string[round(_A )]



     def  UpperCAmelCase__							(				self							:							str ):







       """simple docstring"""




       __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		round(numpy.linalg.det(self.encrypt_key ) )

       if det < 0:
         __SCREAMING_SNAKE_CASE      :	str					=		det % len(self.key_string )

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



     def  UpperCAmelCase__							(				self							:							Optional[Any]     ,						_A							:							str ):







       """simple docstring"""




       __SCREAMING_SNAKE_CASE      :	Any					=		[char for char in text.upper() if char in self.key_string]

       __SCREAMING_SNAKE_CASE      :	str					=		chars[-1]
       while len(_A ) % self.break_key != 0:
         chars.append(_A )

       return "".join(_A )



     def  UpperCAmelCase__							(				self							:							Any     ,						_A							:							str ):







       """simple docstring"""




       __SCREAMING_SNAKE_CASE      :	List[str]					=		self.process_text(text.upper() )
       __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		''''''

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

       return encrypted



     def  UpperCAmelCase__							(				self							:							Optional[int] ):







       """simple docstring"""




       __SCREAMING_SNAKE_CASE      :	Tuple					=		round(numpy.linalg.det(self.encrypt_key ) )

       if det < 0:
         __SCREAMING_SNAKE_CASE      :	str					=		det % len(self.key_string )
       __SCREAMING_SNAKE_CASE      :	List[Any]					=		None
       for i in range(len(self.key_string ) ):
         if (det * i) % len(self.key_string ) == 1:
           __SCREAMING_SNAKE_CASE      :	Optional[int]					=		i
           break

       __SCREAMING_SNAKE_CASE      :	Any					=		(
           det_inv
           * numpy.linalg.det(self.encrypt_key )
           * numpy.linalg.inv(self.encrypt_key )
       )

       return self.to_int(self.modulus(_A ) )




     def  UpperCAmelCase__							(				self							:							Any     ,						_A							:							str ):







       """simple docstring"""




       __SCREAMING_SNAKE_CASE      :	Union[str, Any]					=		self.make_decrypt_key()
       __SCREAMING_SNAKE_CASE      :	str					=		self.process_text(text.upper() )
       __SCREAMING_SNAKE_CASE      :	Optional[int]					=		''''''

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

       return decrypted






def 							a__					(							):





  """simple docstring"""
  __SCREAMING_SNAKE_CASE      :	Any					=		int(input('''Enter the order of the encryption key: '''							)							)
  __SCREAMING_SNAKE_CASE      :	Optional[Any]					=		[]

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

  __SCREAMING_SNAKE_CASE      :	Dict					=		HillCipher(numpy.array(snake_case							)							)

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


if __name__ == "__main__":
   import doctest

   doctest.testmod()

   main()

"""simple docstring"""



import os



def 	_lowerCamelCase(	a = "matrix.txt"				):
       with open(os.path.join(os.path.dirname(a				)   ,    a				)				) as in_file:
              __a       =    in_file.read()

       __a       =    [[int(a				) for cell in row.split(","				)] for row in data.strip().splitlines()]
       __a       =    [[0 for cell in row] for row in grid]
       __a       =    len(grid[0]				)

       __a       =    [[0 for i in range(a				)] for j in range(a				)]
       __a       =    grid[0][0]
       for i in range(1   ,    a				):
              __a       =    grid[0][i] + dp[0][i - 1]
       for i in range(1   ,    a				):
              __a       =    grid[i][0] + dp[i - 1][0]

       for i in range(1   ,    a				):
              for j in range(1   ,    a				):
                     __a       =    grid[i][j] + min(dp[i - 1][j]   ,    dp[i][j - 1]				)

       return dp[-1][-1]


if __name__ == "__main__":
   print(F'''{solution() = }''')
