

from math import factorial






class _UpperCamelCase				:
			'''simple docstring'''







			def __init__(      self				:			Dict   ,   a				:			Optional[int]   ,   a				:			Dict						)				->							Optional[Any]:

				"""simple docstring"""

				SCREAMING_SNAKE_CASE :   Optional[Any]					  =							real
				if isinstance(a   ,   a						):
					SCREAMING_SNAKE_CASE :   Dict					  =							[1] * rank
				else:
					SCREAMING_SNAKE_CASE :   Optional[Any]					  =							rank
			def __repr__(      self				:			List[Any]						)				->							str:

				"""simple docstring"""

				return (
				    F"{self.real}+"
				    F"{'+'.join(str(a						)+'E'+str(n+1						)for n,dual in enumerate(self.duals						)						)}"
				)
			def 				__UpperCamelCase			(      self				:			List[Any]						)				->							Tuple:

				"""simple docstring"""

				SCREAMING_SNAKE_CASE :   Dict					  =							self.duals.copy()
				while cur[-1] == 0:
					cur.pop(-1						)
				return Dual(self.real   ,   a						)
			def __add__(      self				:			Tuple   ,   a				:			List[str]						)				->							List[str]:

				"""simple docstring"""

				if not isinstance(a   ,   a						):
					return Dual(self.real + other   ,   self.duals						)
				SCREAMING_SNAKE_CASE :   List[str]					  =							self.duals.copy()
				SCREAMING_SNAKE_CASE :   Dict					  =							other.duals.copy()
				if len(a						) > len(a						):
					o_dual.extend([1] * (len(a						) - len(a						))						)
				elif len(a						) < len(a						):
					s_dual.extend([1] * (len(a						) - len(a						))						)
				SCREAMING_SNAKE_CASE :   int					  =							[]
				for i in range(len(a						)						):
					new_duals.append(s_dual[i] + o_dual[i]						)
				return Dual(self.real + other.real   ,   a						)

			lowerCamelCase__							     =__add__
			def __sub__(      self				:			Optional[int]   ,   a				:			int						)				->							Dict:

				"""simple docstring"""

				return self + other * -1
			def __mul__(      self				:			Union[str, Any]   ,   a				:			int						)				->							int:

				"""simple docstring"""

				if not isinstance(a   ,   a						):
					SCREAMING_SNAKE_CASE :   Union[str, Any]					  =							[]
					for i in self.duals:
						new_duals.append(i * other						)
					return Dual(self.real * other   ,   a						)
				SCREAMING_SNAKE_CASE :   List[Any]					  =							[0] * (len(self.duals						) + len(other.duals						) + 1)
				for i, item in enumerate(self.duals						):
					for j, jtem in enumerate(other.duals						):
						new_duals[i + j + 1] += item * jtem
				for k in range(len(self.duals						)						):
					new_duals[k] += self.duals[k] * other.real
				for index in range(len(other.duals						)						):
					new_duals[index] += other.duals[index] * self.real
				return Dual(self.real * other.real   ,   a						)

			lowerCamelCase__							     =__mul__
			def __truediv__(      self				:			int   ,   a				:			int						)				->							Optional[int]:

				"""simple docstring"""

				if not isinstance(a   ,   a						):
					SCREAMING_SNAKE_CASE :   int					  =							[]
					for i in self.duals:
						new_duals.append(i / other						)
					return Dual(self.real / other   ,   a						)
				raise ValueError
			def __floordiv__(      self				:			List[Any]   ,   a				:			Optional[int]						)				->							List[Any]:

				"""simple docstring"""

				if not isinstance(a   ,   a						):
					SCREAMING_SNAKE_CASE :   int					  =							[]
					for i in self.duals:
						new_duals.append(i // other						)
					return Dual(self.real // other   ,   a						)
				raise ValueError






			def __pow__(      self				:			Optional[Any]   ,   a				:			Dict						)				->							Optional[Any]:

				"""simple docstring"""

				if n < 0 or isinstance(a   ,   a						):
					raise ValueError("power must be a positive integer"						)
				if n == 0:
					return 1
				if n == 1:
					return self
				SCREAMING_SNAKE_CASE :   List[str]					  =							self
				for _ in range(n - 1						):
					x *= self
				return x

def 			lowerCamelCase__			(       _a				,      _a				,      _a):
	if not callable(_a):
		raise ValueError("differentiate() requires a function as input for func")
	if not isinstance(_a				,      (float, int)):
		raise ValueError("differentiate() requires a float as input for position")
	if not isinstance(_a				,      _a):
		raise ValueError("differentiate() requires an int as input for order")
	SCREAMING_SNAKE_CASE :   Optional[int]					  =							Dual(_a				,      1)
	SCREAMING_SNAKE_CASE :   List[str]					  =							func(_a)
	if order == 0:
		return result.real
	return result.duals[order - 1] * factorial(_a)


if __name__ == "__main__":
			import doctest

			doctest.testmod()

			def 			lowerCamelCase__			(       _a):
				return y**2 * y**4


			print(differentiate(f, 9, 2))

"""simple docstring"""



from __future__ import annotations

UpperCamelCase__          =	tuple[int, int, int]
UpperCamelCase__          =	tuple[str, str, str]


# used alphabet --------------------------
# from string.ascii_uppercase
UpperCamelCase__          =	'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

# -------------------------- default selection --------------------------
# rotors --------------------------
UpperCamelCase__          =	'EGZWVONAHDCLFQMSIPJBYUKXTR'
UpperCamelCase__          =	'FOBHMDKEXQNRAULPGSJVTYICZW'
UpperCamelCase__          =	'ZJXESIUQLHAVRMDOYGTNFWPBKC'
# reflector --------------------------
UpperCamelCase__          =	{
    '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 --------------------------
UpperCamelCase__          =	'RMDJXFUWGISLHVTCQNKYPBEZOA'
UpperCamelCase__          =	'SGLCPQWZHKXAREONTFBVIYJUDM'
UpperCamelCase__          =	'HVSICLTYKQUBXDWAJZOMFGPREN'
UpperCamelCase__          =	'RZWQHFMVDBKICJLNTUXAGYPSOE'
UpperCamelCase__          =	'LFKIJODBEGAMQPXVUHYSTCZRWN'
UpperCamelCase__          =	'KOAEGVDHXPQZMLFTYWJNBRCIUS'
def 					lowerCamelCase   (     _snake_case    ,_snake_case    ,_snake_case ):
    # Checks if there are 3 unique rotors

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

    # Checks if rotor positions are valid
    UpperCAmelCase__							,							UpperCAmelCase__							,							UpperCAmelCase__	:      List[str]     							=					rotpos
    if not 0 < rotorposa <= len(_snake_case ):
        UpperCAmelCase__	:      List[Any]     							=					F'''First rotor position is not within range of 1..26 ({rotorposa}'''
        raise ValueError(_snake_case )
    if not 0 < rotorposa <= len(_snake_case ):
        UpperCAmelCase__	:      Tuple     							=					F'''Second rotor position is not within range of 1..26 ({rotorposa})'''
        raise ValueError(_snake_case )
    if not 0 < rotorposa <= len(_snake_case ):
        UpperCAmelCase__	:      Tuple     							=					F'''Third rotor position is not within range of 1..26 ({rotorposa})'''
        raise ValueError(_snake_case )

    # Validates string and returns dict
    UpperCAmelCase__	:      Optional[int]     							=					_plugboard(_snake_case )

    return rotpos, rotsel, pbdict
def 					lowerCamelCase   (     _snake_case ):

    # tests the input string if it
    # a) is type string
    # b) has even length (so pairs can be made)
    if not isinstance(_snake_case    ,_snake_case ):
        UpperCAmelCase__	:      Union[str, Any]     							=					F'''Plugboard setting isn\'t type string ({type(_snake_case )})'''
        raise TypeError(_snake_case )
    elif len(_snake_case ) % 2 != 0:
        UpperCAmelCase__	:      Dict     							=					F'''Odd number of symbols ({len(_snake_case )})'''
        raise Exception(_snake_case )
    elif pbstring == "":
        return {}

    pbstring.replace(' '    ,'' )

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

    # Created the dictionary
    UpperCAmelCase__	:      str     							=					{}
    for j in range(0    ,len(_snake_case ) - 1    ,2 ):
        UpperCAmelCase__	:      Dict     							=					pbstring[j + 1]
        UpperCAmelCase__	:      int     							=					pbstring[j]

    return pb
def 					lowerCamelCase   (     _snake_case    ,_snake_case    ,_snake_case = (rotora, rotora, rotora)    ,_snake_case = ""    ,):
    UpperCAmelCase__	:      str     							=					text.upper()
    UpperCAmelCase__							,							UpperCAmelCase__							,							UpperCAmelCase__	:      int     							=					_validator(
        _snake_case    ,_snake_case    ,plugb.upper() )

    UpperCAmelCase__							,							UpperCAmelCase__							,							UpperCAmelCase__	:      List[str]     							=					rotor_position
    UpperCAmelCase__							,							UpperCAmelCase__							,							UpperCAmelCase__	:      List[Any]     							=					rotor_selection
    rotorposa -= 1
    rotorposa -= 1
    rotorposa -= 1

    UpperCAmelCase__	:      Any     							=					[]

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

            # rotor ra --------------------------
            UpperCAmelCase__	:      List[str]     							=					abc.index(_snake_case ) + rotorposa
            UpperCAmelCase__	:      Optional[Any]     							=					rotora[index % len(_snake_case )]

            # rotor rb --------------------------
            UpperCAmelCase__	:      Optional[int]     							=					abc.index(_snake_case ) + rotorposa
            UpperCAmelCase__	:      List[Any]     							=					rotora[index % len(_snake_case )]

            # rotor rc --------------------------
            UpperCAmelCase__	:      Optional[Any]     							=					abc.index(_snake_case ) + rotorposa
            UpperCAmelCase__	:      Any     							=					rotora[index % len(_snake_case )]

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

            UpperCAmelCase__	:      Union[str, Any]     							=					reflector[symbol]

            # 2nd rotors
            UpperCAmelCase__	:      List[str]     							=					abc[rotora.index(_snake_case ) - rotorposa]
            UpperCAmelCase__	:      Optional[Any]     							=					abc[rotora.index(_snake_case ) - rotorposa]
            UpperCAmelCase__	:      List[Any]     							=					abc[rotora.index(_snake_case ) - rotorposa]

            # 2nd plugboard
            if symbol in plugboard:
                UpperCAmelCase__	:      int     							=					plugboard[symbol]

            # moves/resets rotor positions
            rotorposa += 1
            if rotorposa >= len(_snake_case ):
                UpperCAmelCase__	:      Dict     							=					0
                rotorposa += 1
            if rotorposa >= len(_snake_case ):
                UpperCAmelCase__	:      Any     							=					0
                rotorposa += 1
            if rotorposa >= len(_snake_case ):
                UpperCAmelCase__	:      int     							=					0

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

    return "".join(_snake_case )


if __name__ == "__main__":
    UpperCamelCase__          =	'This is my Python script that emulates the Enigma machine from WWII.'
    UpperCamelCase__          =	(1, 1, 1)
    UpperCamelCase__          =	'pictures'
    UpperCamelCase__          =	(rotora, rotora, rotora)
    UpperCamelCase__          =	enigma(message, rotor_pos, rotor_sel, pb)

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

