





import string

import numpy




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	)       ->     int:
  return b if a == 0 else greatest_common_divisor(b % a	,		_SCREAMING_SNAKE_CASE	)
class        SCREAMING_SNAKE_CASE     :
   _UpperCamelCase					:	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)
   _UpperCamelCase					:	Dict				      = numpy.vectorize(lambda UpperCAmelCase   : x % 36   )

   _UpperCamelCase					:	List[Any]				      = numpy.vectorize(UpperCAmelCase   )


   def __init__(					self    :       Dict    ,  a    :       numpy.ndarray )->     None:





     """simple docstring"""







     lowercase__			    =						self.modulus(a )  # mod36 calc's on the encrypt key
     self.check_determinant()  # validate the determinant of the encryption key
     lowercase__			    =						encrypt_key.shape[0]


   def  SCREAMING_SNAKE_CASE_							(					self    :       str    ,  a    :       str )->     int:





     """simple docstring"""







     return self.key_string.index(a )


   def  SCREAMING_SNAKE_CASE_							(					self    :       Any    ,  a    :       int )->     str:





     """simple docstring"""







     return self.key_string[round(a )]


   def  SCREAMING_SNAKE_CASE_							(					self    :       Dict )->     None:





     """simple docstring"""







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

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

     lowercase__			    =						len(self.key_string )
     if greatest_common_divisor(a    ,  len(self.key_string ) ) != 1:
       lowercase__			    =						(
           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  SCREAMING_SNAKE_CASE_							(					self    :       Dict    ,  a    :       str )->     str:





     """simple docstring"""







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

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

     return "".join(a )


   def  SCREAMING_SNAKE_CASE_							(					self    :       List[str]    ,  a    :       str )->     str:





     """simple docstring"""







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

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

     return encrypted


   def  SCREAMING_SNAKE_CASE_							(					self    :       int )->     numpy.ndarray:





     """simple docstring"""







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

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

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

     return self.to_int(self.modulus(a ) )


   def  SCREAMING_SNAKE_CASE_							(					self    :       Optional[int]    ,  a    :       str )->     str:





     """simple docstring"""







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

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

     return decrypted






def     __UpperCamelCase						()       ->     None:
  lowercase__			    =						int(input('Enter the order of the encryption key: '	)	)
  lowercase__			    =						[]

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

  lowercase__			    =						HillCipher(numpy.array(_SCREAMING_SNAKE_CASE	)	)

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









def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE = 50	)       ->     int:
  lowercase__			    =						[1] * (length + 1)

  for row_length in range(3	,		length + 1	):
    for block_length in range(3	,		row_length + 1	):
      for block_start in range(row_length - block_length	):
        ways_number[row_length] += ways_number[
            row_length - block_start - block_length - 1
        ]

      ways_number[row_length] += 1

  return ways_number[length]


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


