


from __future__ import annotations

a			:			str												=					tuple[int, int, int]
a			:			Any												=					tuple[str, str, str]


# used alphabet --------------------------
# from string.ascii_uppercase
a			:			Any												=					'''ABCDEFGHIJKLMNOPQRSTUVWXYZ'''

# -------------------------- default selection --------------------------
# rotors --------------------------
a			:			str												=					'''EGZWVONAHDCLFQMSIPJBYUKXTR'''
a			:			Tuple												=					'''FOBHMDKEXQNRAULPGSJVTYICZW'''
a			:			Optional[int]												=					'''ZJXESIUQLHAVRMDOYGTNFWPBKC'''
# reflector --------------------------
a			:			int												=					{
    '''A''': '''N''',
    '''N''': '''A''',
    '''B''': '''O''',
    '''O''': '''B''',
    '''C''': '''P''',
    '''P''': '''C''',
    '''D''': '''Q''',
    '''Q''': '''D''',
    '''E''': '''R''',
    '''R''': '''E''',
    '''F''': '''S''',
    '''S''': '''F''',
    '''G''': '''T''',
    '''T''': '''G''',
    '''H''': '''U''',
    '''U''': '''H''',
    '''I''': '''V''',
    '''V''': '''I''',
    '''J''': '''W''',
    '''W''': '''J''',
    '''K''': '''X''',
    '''X''': '''K''',
    '''L''': '''Y''',
    '''Y''': '''L''',
    '''M''': '''Z''',
    '''Z''': '''M''',
}

# -------------------------- extra rotors --------------------------
a			:			Tuple												=					'''RMDJXFUWGISLHVTCQNKYPBEZOA'''
a			:			Tuple												=					'''SGLCPQWZHKXAREONTFBVIYJUDM'''
a			:			List[str]												=					'''HVSICLTYKQUBXDWAJZOMFGPREN'''
a			:			List[str]												=					'''RZWQHFMVDBKICJLNTUXAGYPSOE'''
a			:			str												=					'''LFKIJODBEGAMQPXVUHYSTCZRWN'''
a			:			List[str]												=					'''KOAEGVDHXPQZMLFTYWJNBRCIUS'''


def 		lowercase_	(  _UpperCamelCase							,      _UpperCamelCase							,      _UpperCamelCase	):


			'''simple docstring'''







			if (unique_rotsel := len(set(_UpperCamelCase	)	)) < 3:
						__lowercase			       = F'Please use 3 unique rotors (not {unique_rotsel})'
						raise Exception(_UpperCamelCase	)

			# Checks if rotor positions are valid
			__lowercase       ,			__lowercase       ,			__lowercase			       = rotpos
			if not 0 < rotorposa <= len(_UpperCamelCase	):
						__lowercase			       = F'First rotor position is not within range of 1..26 ({rotorposa}'
						raise ValueError(_UpperCamelCase	)
			if not 0 < rotorposa <= len(_UpperCamelCase	):
						__lowercase			       = F'Second rotor position is not within range of 1..26 ({rotorposa})'
						raise ValueError(_UpperCamelCase	)
			if not 0 < rotorposa <= len(_UpperCamelCase	):
						__lowercase			       = F'Third rotor position is not within range of 1..26 ({rotorposa})'
						raise ValueError(_UpperCamelCase	)

			# Validates string and returns dict
			__lowercase			       = _plugboard(_UpperCamelCase	)

			return rotpos, rotsel, pbdict


def 		lowercase_	(  _UpperCamelCase	):


			'''simple docstring'''







			if not isinstance(_UpperCamelCase							,      _UpperCamelCase	):
						__lowercase			       = F'Plugboard setting isn\'t type string ({type(_UpperCamelCase	)})'
						raise TypeError(_UpperCamelCase	)
			elif len(_UpperCamelCase	) % 2 != 0:
						__lowercase			       = F'Odd number of symbols ({len(_UpperCamelCase	)})'
						raise Exception(_UpperCamelCase	)
			elif pbstring == "":
						return {}

			pbstring.replace(''' '''							,      ''''''	)

			# Checks if all characters are unique
			__lowercase			       = set()
			for i in pbstring:
						if i not in abc:
									__lowercase			       = F'\'{i}\' not in list of symbols'
									raise Exception(_UpperCamelCase	)
						elif i in tmppbl:
									__lowercase			       = F'Duplicate symbol ({i})'
									raise Exception(_UpperCamelCase	)
						else:
									tmppbl.add(_UpperCamelCase	)
			del tmppbl

			# Created the dictionary
			__lowercase			       = {}
			for j in range(0							,      len(_UpperCamelCase	) - 1							,      2	):
						__lowercase			       = pbstring[j + 1]
						__lowercase			       = pbstring[j]

			return pb


def 		lowercase_	(  _UpperCamelCase							,      _UpperCamelCase							,      _UpperCamelCase = (rotora, rotora, rotora)							,      _UpperCamelCase = ""							,      ):


			'''simple docstring'''







			__lowercase			       = text.upper()
			__lowercase       ,			__lowercase       ,			__lowercase			       = _validator(
			    _UpperCamelCase							,      _UpperCamelCase							,      plugb.upper()	)

			__lowercase       ,			__lowercase       ,			__lowercase			       = rotor_position
			__lowercase       ,			__lowercase       ,			__lowercase			       = rotor_selection
			rotorposa -= 1
			rotorposa -= 1
			rotorposa -= 1

			__lowercase			       = []

			# encryption/decryption process --------------------------
			for symbol in text:
						if symbol in abc:
									# 1st plugboard --------------------------
									if symbol in plugboard:
												__lowercase			       = plugboard[symbol]

									# rotor ra --------------------------
									__lowercase			       = abc.index(_UpperCamelCase	) + rotorposa
									__lowercase			       = rotora[index % len(_UpperCamelCase	)]

									# rotor rb --------------------------
									__lowercase			       = abc.index(_UpperCamelCase	) + rotorposa
									__lowercase			       = rotora[index % len(_UpperCamelCase	)]

									# rotor rc --------------------------
									__lowercase			       = abc.index(_UpperCamelCase	) + rotorposa
									__lowercase			       = rotora[index % len(_UpperCamelCase	)]

									# reflector --------------------------
									# this is the reason you don't need another machine to decipher

									__lowercase			       = reflector[symbol]

									# 2nd rotors
									__lowercase			       = abc[rotora.index(_UpperCamelCase	) - rotorposa]
									__lowercase			       = abc[rotora.index(_UpperCamelCase	) - rotorposa]
									__lowercase			       = abc[rotora.index(_UpperCamelCase	) - rotorposa]

									# 2nd plugboard
									if symbol in plugboard:
												__lowercase			       = plugboard[symbol]

									# moves/resets rotor positions
									rotorposa += 1
									if rotorposa >= len(_UpperCamelCase	):
												__lowercase			       = 0
												rotorposa += 1
									if rotorposa >= len(_UpperCamelCase	):
												__lowercase			       = 0
												rotorposa += 1
									if rotorposa >= len(_UpperCamelCase	):
												__lowercase			       = 0

        # else:
        #    pass
        #    Error could be also raised
        #    raise ValueError(
        #       'Invalid symbol('+repr(symbol)+')')
						result.append(_UpperCamelCase	)

			return "".join(_UpperCamelCase	)


if __name__ == "__main__":
	a			:			List[str]												=					'''This is my Python script that emulates the Enigma machine from WWII.'''
	a			:			str												=					(1, 1, 1)
	a			:			List[Any]												=					'''pictures'''
	a			:			str												=					(rotora, rotora, rotora)
	a			:			Union[str, Any]												=					enigma(message, rotor_pos, rotor_sel, pb)

	print('''Encrypted message:''', en)
	print('''Decrypted message:''', enigma(en, rotor_pos, rotor_sel, pb))






a			:			Any												=					[sum(int(c, 10) ** 2 for c in i.__str__()) for i in range(100000)]


def 		lowercase_	(  _UpperCamelCase	):


			'''simple docstring'''







			__lowercase			       = 0
			while number:
						# Increased Speed Slightly by checking every 5 digits together.
						sum_of_digits_squared += DIGITS_SQUARED[number % 10_00_00]
						number //= 10_00_00

			return sum_of_digits_squared


# There are 2 Chains made,
# One ends with 89 with the chain member 58 being the one which when declared first,
# there will be the least number of iterations for all the members to be checked.

# The other one ends with 1 and has only one element 1.

# So 58 and 1 are chosen to be declared at the starting.

# Changed dictionary to an array to quicken the solution
a			:			list[bool | None]												=					[None] * 10000000
a			:			int												=					True
a			:			Any												=					False


def 		lowercase_	(  _UpperCamelCase	):


			'''simple docstring'''







			if CHAINS[number - 1] is not None:
						return CHAINS[number - 1]  # type: ignore

			__lowercase			       = chain(next_number(_UpperCamelCase	)	)
			__lowercase			       = number_chain

			while number < 10_00_00_00:
						__lowercase			       = number_chain
						number *= 10

			return number_chain


def 		lowercase_	(  _UpperCamelCase = 10_00_00_00	):


			'''simple docstring'''







			for i in range(1							,      _UpperCamelCase	):
						if CHAINS[i] is None:
									chain(i + 1	)

			return CHAINS[:number].count(_UpperCamelCase	)


if __name__ == "__main__":
	import doctest

	doctest.testmod()
	print(f'''{solution() = }''')


