




'''simple docstring'''







import string

import numpy





def 						snake_case_							(_a	:							int    ,   _a	:							int     ):
    return b if a == 0 else greatest_common_divisor(b % a    ,   SCREAMING_SNAKE_CASE__     )


class 			_a  :
       __a				:     List[Any]   				=					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)
       __a				:     Dict   				=					numpy.vectorize(lambda __a : x % 36 )

       __a				:     List[str]   				=					numpy.vectorize(_UpperCAmelCase )
       def __init__(	self						:	List[Any]   ,				lowercase						:	numpy.ndarray				):



           '''simple docstring'''

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



           '''simple docstring'''

           return self.key_string.index(lowercase_				)
       def     A      (	self						:	List[str]   ,				lowercase						:	int				):



           '''simple docstring'''

           return self.key_string[round(lowercase_				)]
       def     A      (	self						:	List[Any]				):



           '''simple docstring'''

           UpperCAmelCase			       =		round(numpy.linalg.det(self.encrypt_key				)				)

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

           UpperCAmelCase			       =		len(self.key_string				)
           if greatest_common_divisor(lowercase_   ,				len(self.key_string				)				) != 1:
               UpperCAmelCase			       =		(
                   f"determinant modular {req_l} of encryption key({det}) "
                   f"is not co prime w.r.t {req_l}.\nTry another key."
               )
               raise ValueError(lowercase_				)
       def     A      (	self						:	Dict   ,				lowercase						:	str				):



           '''simple docstring'''

           UpperCAmelCase			       =		[char for char in text.upper() if char in self.key_string]

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

           return "".join(lowercase_				)
       def     A      (	self						:	Any   ,				lowercase						:	str				):



           '''simple docstring'''

           UpperCAmelCase			       =		self.process_text(text.upper()				)
           UpperCAmelCase			       =		''''''

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

           return encrypted
       def     A      (	self						:	Optional[int]				):



           '''simple docstring'''

           UpperCAmelCase			       =		round(numpy.linalg.det(self.encrypt_key				)				)

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

           UpperCAmelCase			       =		(
               det_inv
               * numpy.linalg.det(self.encrypt_key				)
               * numpy.linalg.inv(self.encrypt_key				)
           )

           return self.to_int(self.modulus(lowercase_				)				)







       def     A      (	self						:	Optional[Any]   ,				lowercase						:	str				):



           '''simple docstring'''

           UpperCAmelCase			       =		self.make_decrypt_key()
           UpperCAmelCase			       =		self.process_text(text.upper()				)
           UpperCAmelCase			       =		''''''

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

           return decrypted






def 						snake_case_							():
    UpperCAmelCase			       =		int(input('''Enter the order of the encryption key: '''     )     )
    UpperCAmelCase			       =		[]

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

    UpperCAmelCase			       =		HillCipher(numpy.array(SCREAMING_SNAKE_CASE__     )     )

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


if __name__ == "__main__":
   import doctest

   doctest.testmod()

   main()







import os

# Precomputes a list of the 100 first triangular numbers
lowercase_       		=  [int(0.5 * n * (n + 1)) for n in range(1, 101)]
def 						_snake_case(    )							->      int:





    '''simple docstring'''






    A__          =   os.path.dirname(os.path.realpath(SCREAMING_SNAKE_CASE__      )      )
    A__          =   os.path.join(SCREAMING_SNAKE_CASE__    ,			'words.txt'      )

    A__          =   ''
    with open(SCREAMING_SNAKE_CASE__      ) as f:
        A__          =   f.readline()

    A__          =   [word.strip('"'      ) for word in words.strip('\r\n'      ).split(','      )]
    A__          =   [
        word
        for word in [sum(ord(SCREAMING_SNAKE_CASE__      ) - 64 for x in word      ) for word in words]
        if word in TRIANGULAR_NUMBERS
    ]
    return len(SCREAMING_SNAKE_CASE__      )


if __name__ == "__main__":
     print(solution())

