



'''simple docstring'''




import string

import numpy



def    __lowerCamelCase						(      _lowercase			,       _lowercase	)   ->    Any:
       return b if a == 0 else greatest_common_divisor(b % a			,       _snake_case	)

class     UpperCamelCase_				:
 lowercase    =				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)
 lowercase    =				numpy.vectorize(lambda __magic_name__    : x % 36    )

 lowercase    =				numpy.vectorize(__magic_name__    )





 def __init__(						self	,	A					)    ->    str:
        UpperCAmelCase  :	Optional[Any]							  =	self.modulus(A					)  # mod36 calc's on the encrypt key
        self.check_determinant()  # validate the determinant of the encryption key
        UpperCAmelCase  :	Any							  =	encrypt_key.shape[0]





 def 				_lowercase(						self	,	A					)    ->    Union[str, Any]:
        return self.key_string.index(A					)





 def 				_lowercase(						self	,	A					)    ->    List[str]:
        return self.key_string[round(A					)]





 def 				_lowercase(						self					)    ->    Optional[Any]:
        UpperCAmelCase  :	Dict							  =	round(numpy.linalg.det(self.encrypt_key					)					)

        if det < 0:
               UpperCAmelCase  :	int							  =	det % len(self.key_string					)

        UpperCAmelCase  :	Any							  =	len(self.key_string					)
        if greatest_common_divisor(A	,	len(self.key_string					)					) != 1:
               UpperCAmelCase  :	List[str]							  =	(
                   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 				_lowercase(						self	,	A					)    ->    Optional[int]:
        UpperCAmelCase  :	Any							  =	[char for char in text.upper() if char in self.key_string]

        UpperCAmelCase  :	Tuple							  =	chars[-1]
        while len(A					) % self.break_key != 0:
               chars.append(A					)

        return "".join(A					)





 def 				_lowercase(						self	,	A					)    ->    List[str]:
        UpperCAmelCase  :	Optional[int]							  =	self.process_text(text.upper()					)
        UpperCAmelCase  :	str							  =	""""""

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

        return encrypted





 def 				_lowercase(						self					)    ->    Union[str, Any]:
        UpperCAmelCase  :	Any							  =	round(numpy.linalg.det(self.encrypt_key					)					)

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

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

        return self.to_int(self.modulus(A					)					)






 def 				_lowercase(						self	,	A					)    ->    int:
        UpperCAmelCase  :	Union[str, Any]							  =	self.make_decrypt_key()
        UpperCAmelCase  :	Optional[int]							  =	self.process_text(text.upper()					)
        UpperCAmelCase  :	Optional[Any]							  =	""""""

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

        return decrypted




def    __lowerCamelCase						(      )   ->    int:
       UpperCAmelCase  :	Optional[Any]							  =	int(input("""Enter the order of the encryption key: """	)	)
       UpperCAmelCase  :	Dict							  =	[]

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

       UpperCAmelCase  :	Tuple							  =	HillCipher(numpy.array(_snake_case	)	)

       print("""Would you like to encrypt or decrypt some text? (1 or 2)"""	)
       UpperCAmelCase  :	List[str]							  =	input("""\n1. Encrypt\n2. Decrypt\n"""	)
       if option == "1":
              UpperCAmelCase  :	Tuple							  =	input("""What text would you like to encrypt?: """	)
              print("""Your encrypted text is:"""	)
              print(hc.encrypt(_snake_case	)	)
       elif option == "2":
              UpperCAmelCase  :	Optional[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'''




from collections.abc import Callable

import numpy as np



def    __lowerCamelCase						(      _lowercase			,       _lowercase			,       _lowercase			,       _lowercase			,       _lowercase	)   ->    np.array:
							UpperCAmelCase  :	Optional[Any]							  =	int(np.ceil((x_end - xa) / step_size	)	)
							UpperCAmelCase  :	str							  =	np.zeros((n + 1,)	)
							UpperCAmelCase  :	Optional[Any]							  =	ya
							UpperCAmelCase  :	Union[str, Any]							  =	xa

							for k in range(_lowercase	):
														UpperCAmelCase  :	Dict							  =	y[k] + step_size * ode_func(_lowercase			,       y[k]	)
														UpperCAmelCase  :	Optional[int]							  =	y[k] + (
														    (step_size / 2) * (ode_func(_lowercase			,       y[k]	) + ode_func(x + step_size			,       _lowercase	))
														)
														x += step_size

							return y


if __name__ == "__main__":
							import doctest

							doctest.testmod()

