from __future__ import annotations

__lowerCamelCase	:					Tuple			  =					tuple[int, int, int]
__lowerCamelCase	:					Tuple			  =					tuple[str, str, str]


# used alphabet --------------------------
# from string.ascii_uppercase
__lowerCamelCase	:					List[Any]			  =					"""ABCDEFGHIJKLMNOPQRSTUVWXYZ"""

# -------------------------- default selection --------------------------
# rotors --------------------------
__lowerCamelCase	:					str			  =					"""EGZWVONAHDCLFQMSIPJBYUKXTR"""
__lowerCamelCase	:					Dict			  =					"""FOBHMDKEXQNRAULPGSJVTYICZW"""
__lowerCamelCase	:					Union[str, Any]			  =					"""ZJXESIUQLHAVRMDOYGTNFWPBKC"""
# reflector --------------------------
__lowerCamelCase	:					Optional[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 --------------------------
__lowerCamelCase	:					Optional[Any]			  =					"""RMDJXFUWGISLHVTCQNKYPBEZOA"""
__lowerCamelCase	:					List[Any]			  =					"""SGLCPQWZHKXAREONTFBVIYJUDM"""
__lowerCamelCase	:					str			  =					"""HVSICLTYKQUBXDWAJZOMFGPREN"""
__lowerCamelCase	:					Tuple			  =					"""RZWQHFMVDBKICJLNTUXAGYPSOE"""
__lowerCamelCase	:					Union[str, Any]			  =					"""LFKIJODBEGAMQPXVUHYSTCZRWN"""
__lowerCamelCase	:					Dict			  =					"""KOAEGVDHXPQZMLFTYWJNBRCIUS"""



def 		A_    (					_lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase					)						->			List[str]:





 if (unique_rotsel := len(set(a__					)					)) < 3:
  UpperCamelCase     : Dict	     =       F"""Please use 3 unique rotors (not {unique_rotsel})"""
  raise Exception(a__					)

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

 # Validates string and returns dict
 UpperCamelCase     : Dict	     =       _plugboard(a__					)

 return rotpos, rotsel, pbdict



def 		A_    (					_lowerCAmelCase					)						->			Any:





 if not isinstance(a__							,       a__					):
  UpperCamelCase     : List[str]	     =       F"""Plugboard setting isn't type string ({type(a__					)})"""
  raise TypeError(a__					)
 elif len(a__					) % 2 != 0:
  UpperCamelCase     : Optional[Any]	     =       F"""Odd number of symbols ({len(a__					)})"""
  raise Exception(a__					)
 elif pbstring == "":
  return {}

 pbstring.replace(" "							,       ""					)

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

 # Created the dictionary
 UpperCamelCase     : Dict	     =       {}
 for j in range(0							,       len(a__					) - 1							,       2					):
  UpperCamelCase     : Optional[Any]	     =       pbstring[j + 1]
  UpperCamelCase     : Tuple	     =       pbstring[j]

 return pb



def 		A_    (					_lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase = (rotora, rotora, rotora)							,       _lowerCAmelCase = ""							,       )						->			str:
 UpperCamelCase     : Tuple	     =       text.upper()
 UpperCamelCase     ,   UpperCamelCase     ,   UpperCamelCase     : Any	     =       _validator(
     a__							,       a__							,       plugb.upper()					)

 UpperCamelCase     ,   UpperCamelCase     ,   UpperCamelCase     : Dict	     =       rotor_position
 UpperCamelCase     ,   UpperCamelCase     ,   UpperCamelCase     : Optional[Any]	     =       rotor_selection
 rotorposa -= 1
 rotorposa -= 1
 rotorposa -= 1

 UpperCamelCase     : Optional[int]	     =       []

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

   # rotor ra --------------------------
   UpperCamelCase     : Union[str, Any]	     =       abc.index(a__					) + rotorposa
   UpperCamelCase     : int	     =       rotora[index % len(a__					)]

   # rotor rb --------------------------
   UpperCamelCase     : str	     =       abc.index(a__					) + rotorposa
   UpperCamelCase     : Tuple	     =       rotora[index % len(a__					)]

   # rotor rc --------------------------
   UpperCamelCase     : List[str]	     =       abc.index(a__					) + rotorposa
   UpperCamelCase     : int	     =       rotora[index % len(a__					)]

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

   UpperCamelCase     : Tuple	     =       reflector[symbol]

   # 2nd rotors
   UpperCamelCase     : Union[str, Any]	     =       abc[rotora.index(a__					) - rotorposa]
   UpperCamelCase     : int	     =       abc[rotora.index(a__					) - rotorposa]
   UpperCamelCase     : Dict	     =       abc[rotora.index(a__					) - rotorposa]

   # 2nd plugboard
   if symbol in plugboard:
    UpperCamelCase     : Tuple	     =       plugboard[symbol]

   # moves/resets rotor positions
   rotorposa += 1
   if rotorposa >= len(a__					):
    UpperCamelCase     : List[Any]	     =       0
    rotorposa += 1
   if rotorposa >= len(a__					):
    UpperCamelCase     : Optional[Any]	     =       0
    rotorposa += 1
   if rotorposa >= len(a__					):
    UpperCamelCase     : int	     =       0

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

 return "".join(a__					)


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

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







from __future__ import annotations

import numpy as np
from numpy import floataa
from numpy.typing import NDArray



def 		A_    (					_lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase							,       _lowerCAmelCase							,       )						->			list[float]:
 UpperCamelCase     ,   UpperCamelCase     : List[Any]	     =       coefficient_matrix.shape
 UpperCamelCase     ,   UpperCamelCase     : Optional[int]	     =       constant_matrix.shape

 if rowsa != colsa:
  UpperCamelCase     : List[Any]	     =       F"""Coefficient matrix dimensions must be nxn but received {rowsa}x{colsa}"""
  raise ValueError(_lowerCAmelCase					)

 if colsa != 1:
  UpperCamelCase     : Any	     =       F"""Constant matrix must be nx1 but received {rowsa}x{colsa}"""
  raise ValueError(_lowerCAmelCase					)

 if rowsa != rowsa:
  UpperCamelCase     : Tuple	     =       (
      "Coefficient and constant matrices dimensions must be nxn and nx1 but "
      F"""received {rowsa}x{colsa} and {rowsa}x{colsa}"""
  )
  raise ValueError(_lowerCAmelCase					)

 if len(_lowerCAmelCase					) != rowsa:
  UpperCamelCase     : Any	     =       (
      "Number of initial values must be equal to number of rows in coefficient "
      F"""matrix but received {len(_lowerCAmelCase					)} and {rowsa}"""
  )
  raise ValueError(_lowerCAmelCase					)

 if iterations <= 0:
  raise ValueError("Iterations must be at least 1"					)

 UpperCamelCase     : NDArray[floataa]	     =       np.concatenate(
     (coefficient_matrix, constant_matrix)							,       axis=1					)

 UpperCamelCase     ,   UpperCamelCase     : str	     =       table.shape

 strictly_diagonally_dominant(_lowerCAmelCase					)

 # Iterates the whole matrix for given number of times
 for _ in range(_lowerCAmelCase					):
  UpperCamelCase     : Optional[Any]	     =       []
  for row in range(_lowerCAmelCase					):
   UpperCamelCase     : Optional[int]	     =       0
   for col in range(_lowerCAmelCase					):
    if col == row:
     UpperCamelCase     : Union[str, Any]	     =       table[row][col]
    elif col == cols - 1:
     UpperCamelCase     : List[Any]	     =       table[row][col]
    else:
     temp += (-1) * table[row][col] * init_val[col]
   UpperCamelCase     : Dict	     =       (temp + val) / denom
   new_val.append(_lowerCAmelCase					)
  UpperCamelCase     : List[str]	     =       new_val

 return [float(_lowerCAmelCase					) for i in new_val]



def 		A_    (					_lowerCAmelCase					)						->			bool:
 UpperCamelCase     ,   UpperCamelCase     : Dict	     =       table.shape

 UpperCamelCase     : List[Any]	     =       True

 for i in range(0							,       _lowerCAmelCase					):
  UpperCamelCase     : Union[str, Any]	     =       0
  for j in range(0							,       cols - 1					):
   if i == j:
    continue
   else:
    total += table[i][j]

  if table[i][i] <= total:
   raise ValueError("Coefficient matrix is not strictly diagonally dominant"					)

 return is_diagonally_dominant


# Test Cases
if __name__ == "__main__":
    import doctest

    doctest.testmod()
