"""simple docstring"""

import string

import numpy






def 	lowercase						(		a__      :						int					,    a__      :						int	)		->  int:
					return b if a == 0 else greatest_common_divisor(b % a					,    _snake_case	)







class 	UpperCAmelCase_			:
							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)
							snake_case__								= numpy.vectorize(lambda _lowercase: x % 36)

							snake_case__								= numpy.vectorize(_lowercase)






							def __init__(						self					: List[str]	,		__UpperCamelCase					: int    )			->			None:
												_UpperCamelCase 		=      self.modulus(UpperCAmelCase_    )  # mod36 calc's on the encrypt key
												self.check_determinant()  # validate the determinant of the encryption key
												_UpperCamelCase 		=      encrypt_key.shape[0]






							def  _UpperCamelCase     (						self					: int	,		__UpperCamelCase					: Any    )			->			int:
												return self.key_string.index(UpperCAmelCase_    )






							def  _UpperCamelCase     (						self					: Optional[Any]	,		__UpperCamelCase					: int    )			->			str:
												return self.key_string[round(UpperCAmelCase_    )]






							def  _UpperCamelCase     (						self					: Any    )			->			None:
												_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(UpperCAmelCase_	,		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(UpperCAmelCase_    )






							def  _UpperCamelCase     (						self					: List[Any]	,		__UpperCamelCase					: Any    )			->			str:
												_UpperCamelCase 		=      [char for char in text.upper() if char in self.key_string]

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

												return "".join(UpperCAmelCase_    )






							def  _UpperCamelCase     (						self					: List[Any]	,		__UpperCamelCase					: Optional[Any]    )			->			str:
												_UpperCamelCase 		=      self.process_text(text.upper()    )
												_UpperCamelCase 		=      ''''''

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

												return encrypted






							def  _UpperCamelCase     (						self					: Union[str, Any]    )			->			numpy.ndarray:
												_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(UpperCAmelCase_    )    )






							def  _UpperCamelCase     (						self					: str	,		__UpperCamelCase					: Union[str, Any]    )			->			str:
												_UpperCamelCase 		=      self.make_decrypt_key()
												_UpperCamelCase 		=      self.process_text(text.upper()    )
												_UpperCamelCase 		=      ''''''

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

												return decrypted






def 	lowercase						(		)		->  Optional[int]:
					_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(_snake_case	):
										_UpperCamelCase 		=      [int(_snake_case	) for x in input().split()]
										hill_matrix.append(_snake_case	)

					_UpperCamelCase 		=      HillCipher(numpy.array(_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(_snake_case	)	)
					elif option == "2":
										_UpperCamelCase 		=      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 json
import os
import unittest

from transformers import MgpstrTokenizer
from transformers.models.mgp_str.tokenization_mgp_str import VOCAB_FILES_NAMES
from transformers.testing_utils import require_tokenizers

from ...test_tokenization_common import TokenizerTesterMixin


@require_tokenizers
class 					snake_case			(UpperCamelCase		,   unittest.TestCase ):
       lowerCAmelCase__	:str     =       MgpstrTokenizer
       lowerCAmelCase__	:Tuple     =       False
       lowerCAmelCase__	:Any     =       {}
       lowerCAmelCase__	:List[Any]     =       False



       def 				_a   (					self   )	->				Union[str, Any]:
           super().setUp()

           # fmt: off
           lowercase__									=    ["[GO]", "[s]", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
           # fmt: on
           lowercase__									=    dict(zip(UpperCAmelCase_  ,range(len(UpperCAmelCase_   )   )   )   )

           lowercase__									=    os.path.join(self.tmpdirname  ,VOCAB_FILES_NAMES["vocab_file"]   )
           with open(self.vocab_file  ,"w"  ,encoding="utf-8"   ) as fp:
               fp.write(json.dumps(UpperCAmelCase_   ) + "\n"   )



       def 				_a   (					self  ,**UpperCAmelCase_   )	->				Any:
           return MgpstrTokenizer.from_pretrained(self.tmpdirname  ,**UpperCAmelCase_   )



       def 				_a   (					self  ,UpperCAmelCase_   )	->				Dict:
           lowercase__									=    "tester"
           lowercase__									=    "tester"
           return input_text, output_text



       @unittest.skip("MGP-STR always lower cases letters."   )
       def 				_a   (					self   )	->				Dict:
           pass



       def 				_a   (					self   )	->				Optional[Any]:
           lowercase__									=    self.get_tokenizers(do_lower_case=UpperCAmelCase_   )
           for tokenizer in tokenizers:
               with self.subTest(F'''{tokenizer.__class__.__name__}'''   ):
                   lowercase__									=    "[SPECIAL_TOKEN]"

                   tokenizer.add_special_tokens({"cls_token": special_token}   )
                   lowercase__									=    tokenizer.encode([special_token]  ,add_special_tokens=UpperCAmelCase_   )
                   self.assertEqual(len(UpperCAmelCase_   )  ,1   )

                   lowercase__									=    tokenizer.decode(UpperCAmelCase_  ,skip_special_tokens=UpperCAmelCase_   )
                   self.assertTrue(special_token not in decoded   )



       def 				_a   (					self   )	->				str:
           lowercase__									=    self.get_tokenizers()
           for tokenizer in tokenizers:
               with self.subTest(F'''{tokenizer.__class__.__name__}'''   ):
                   lowercase__							,							lowercase__									=    self.get_input_output_texts(UpperCAmelCase_   )

                   lowercase__									=    tokenizer.tokenize(UpperCAmelCase_   )
                   lowercase__									=    tokenizer.convert_tokens_to_ids(UpperCAmelCase_   )
                   lowercase__									=    tokenizer.encode(UpperCAmelCase_  ,add_special_tokens=UpperCAmelCase_   )
                   self.assertListEqual(UpperCAmelCase_  ,UpperCAmelCase_   )

                   lowercase__									=    tokenizer.convert_ids_to_tokens(UpperCAmelCase_   )
                   self.assertNotEqual(len(UpperCAmelCase_   )  ,0   )
                   lowercase__									=    tokenizer.decode(UpperCAmelCase_   )
                   self.assertIsInstance(UpperCAmelCase_  ,UpperCAmelCase_   )

                   self.assertEqual(text_a.replace(" "  ,""   )  ,UpperCAmelCase_   )



       @unittest.skip("MGP-STR tokenizer only handles one sequence."   )
       def 				_a   (					self   )	->				Optional[int]:
           pass







       @unittest.skip("inputs cannot be pretokenized in MgpstrTokenizer"   )
       def 				_a   (					self   )	->				Any:
           pass




