





from __future__ import annotations

import math
import random
from collections.abc import Collection
from typing import overload
class SCREAMING_SNAKE_CASE_						:






						def __init__(      self      :      int		,   _A      :      Collection[float] | None = None	)							->    None:







							"""simple docstring"""


							if components is None:
								snake_case_		:			Dict											=	[]
							snake_case_		:			Optional[Any]											=	list(_A	)






						def __len__(      self      :      Dict	)							->    int:







							"""simple docstring"""


							return len(self.__components	)






						def __str__(      self      :      Any	)							->    str:







							"""simple docstring"""


							return "(" + ",".join(map(_A		,   self.__components	)	) + ")"






						def __add__(      self      :      Optional[Any]		,   _A      :      Vector	)							->    Vector:







							"""simple docstring"""


							snake_case_		:			Optional[int]											=	len(self	)
							if size == len(_A	):
								snake_case_		:			Any											=	[self.__components[i] + other.component(_A	) for i in range(_A	)]
								return Vector(_A	)
							else:
								raise Exception('must have the same size'	)






						def __sub__(      self      :      List[Any]		,   _A      :      Vector	)							->    Vector:







							"""simple docstring"""


							snake_case_		:			str											=	len(self	)
							if size == len(_A	):
								snake_case_		:			List[str]											=	[self.__components[i] - other.component(_A	) for i in range(_A	)]
								return Vector(_A	)
							else:  # error case
								raise Exception('must have the same size'	)






						@overload
						def __mul__(      self      :      Any		,   _A      :      float	)							->    Vector:







							"""simple docstring"""


							...






						@overload
						def __mul__(      self      :      str		,   _A      :      Vector	)							->    float:







							"""simple docstring"""


							...






						def __mul__(      self      :      List[Any]		,   _A      :      float | Vector	)							->    float | Vector:







							"""simple docstring"""


							if isinstance(_A		,   (float, int)	):
								snake_case_		:			List[Any]											=	[c * other for c in self.__components]
								return Vector(_A	)
							elif isinstance(_A		,   _A	) and len(self	) == len(_A	):
								snake_case_		:			Tuple											=	len(self	)
								snake_case_		:			Dict											=	[self.__components[i] * other.component(_A	) for i in range(_A	)]
								return sum(_A	)
							else:  # error case
								raise Exception('invalid operand!'	)






						def UpperCAmelCase_				(      self      :      Union[str, Any]	)							->    Vector:







							"""simple docstring"""


							return Vector(self.__components	)






						def UpperCAmelCase_				(      self      :      Tuple		,   _A      :      int	)							->    float:







							"""simple docstring"""


							if isinstance(_A		,   _A	) and -len(self.__components	) <= i < len(self.__components	):
								return self.__components[i]
							else:
								raise Exception('index out of range'	)






						def UpperCAmelCase_				(      self      :      Dict		,   _A      :      int		,   _A      :      float	)							->    None:







							"""simple docstring"""


							assert -len(self.__components	) <= pos < len(self.__components	)
							snake_case_		:			str											=	value






						def UpperCAmelCase_				(      self      :      Union[str, Any]	)							->    float:







							"""simple docstring"""


							if len(self.__components	) == 0:
								raise Exception('Vector is empty'	)
							snake_case_		:			int											=	[c**2 for c in self.__components]
							return math.sqrt(sum(_A	)	)






						def UpperCAmelCase_				(      self      :      str		,   _A      :      Vector		,   _A      :      bool = False	)							->    float:







							"""simple docstring"""


							snake_case_		:			str											=	self * other
							snake_case_		:			int											=	self.euclidean_length() * other.euclidean_length()
							if deg:
								return math.degrees(math.acos(num / den	)	)
							else:
								return math.acos(num / den	)


def 							SCREAMING_SNAKE_CASE__						(    __a   ):
	assert isinstance(__a   , __a   )
	return Vector([0] * dimension   )


def 							SCREAMING_SNAKE_CASE__						(    __a   , __a   ):
	assert isinstance(__a   , __a   ) and (isinstance(__a   , __a   ))
	snake_case_		:			Dict											=	[0] * dimension
	snake_case_		:			str											=	1
	return Vector(__a   )


def 							SCREAMING_SNAKE_CASE__						(    __a   , __a   , __a   ):
	assert (
	    isinstance(__a   , __a   )
	    and isinstance(__a   , __a   )
	    and (isinstance(__a   , (int, float)   ))
	)
	return x * scalar + y


def 							SCREAMING_SNAKE_CASE__						(    __a   , __a   , __a   ):
	random.seed(__a   )
	snake_case_		:			List[Any]											=	[random.randint(__a   , __a   ) for _ in range(__a   )]
	return Vector(__a   )
class SCREAMING_SNAKE_CASE_						:






						def __init__(      self      :      List[Any]		,   _A      :      list[list[float]]		,   _A      :      int		,   _A      :      int	)							->    None:







							"""simple docstring"""


							snake_case_		:			Dict											=	matrix
							snake_case_		:			Tuple											=	w
							snake_case_		:			Any											=	h






						def __str__(      self      :      Union[str, Any]	)							->    str:







							"""simple docstring"""


							snake_case_		:			List[Any]											=	''
							for i in range(self.__height	):
								ans += "|"
								for j in range(self.__width	):
									if j < self.__width - 1:
										ans += str(self.__matrix[i][j]	) + ","
									else:
										ans += str(self.__matrix[i][j]	) + "|\n"
							return ans






						def __add__(      self      :      Optional[int]		,   _A      :      Matrix	)							->    Matrix:







							"""simple docstring"""


							if self.__width == other.width() and self.__height == other.height():
								snake_case_		:			Optional[Any]											=	[]
								for i in range(self.__height	):
									snake_case_		:			Optional[Any]											=	[
									    self.__matrix[i][j] + other.component(_A		,   _A	)
									    for j in range(self.__width	)
									]
									matrix.append(_A	)
								return Matrix(_A		,   self.__width		,   self.__height	)
							else:
								raise Exception('matrix must have the same dimension!'	)






						def __sub__(      self      :      Dict		,   _A      :      Matrix	)							->    Matrix:







							"""simple docstring"""


							if self.__width == other.width() and self.__height == other.height():
								snake_case_		:			List[str]											=	[]
								for i in range(self.__height	):
									snake_case_		:			Optional[int]											=	[
									    self.__matrix[i][j] - other.component(_A		,   _A	)
									    for j in range(self.__width	)
									]
									matrix.append(_A	)
								return Matrix(_A		,   self.__width		,   self.__height	)
							else:
								raise Exception('matrices must have the same dimension!'	)






						@overload
						def __mul__(      self      :      int		,   _A      :      float	)							->    Matrix:







							"""simple docstring"""


							...






						@overload
						def __mul__(      self      :      str		,   _A      :      Vector	)							->    Vector:







							"""simple docstring"""


							...






						def __mul__(      self      :      Union[str, Any]		,   _A      :      float | Vector	)							->    Vector | Matrix:







							"""simple docstring"""


							if isinstance(_A		,   _A	):  # matrix-vector
								if len(_A	) == self.__width:
									snake_case_		:			Optional[Any]											=	zero_vector(self.__height	)
									for i in range(self.__height	):
										snake_case_		:			Union[str, Any]											=	[
										    self.__matrix[i][j] * other.component(_A	)
										    for j in range(self.__width	)
										]
										ans.change_component(_A		,   sum(_A	)	)
									return ans
								else:
									raise Exception(
									    'vector must have the same size as the '
									    'number of columns of the matrix!'	)
							elif isinstance(_A		,   (int, float)	):  # matrix-scalar
								snake_case_		:			Tuple											=	[
								    [self.__matrix[i][j] * other for j in range(self.__width	)]
								    for i in range(self.__height	)
								]
								return Matrix(_A		,   self.__width		,   self.__height	)
							return None






						def UpperCAmelCase_				(      self      :      str	)							->    int:







							"""simple docstring"""


							return self.__height






						def UpperCAmelCase_				(      self      :      Tuple	)							->    int:







							"""simple docstring"""


							return self.__width






						def UpperCAmelCase_				(      self      :      List[Any]		,   _A      :      int		,   _A      :      int	)							->    float:







							"""simple docstring"""


							if 0 <= x < self.__height and 0 <= y < self.__width:
								return self.__matrix[x][y]
							else:
								raise Exception('change_component: indices out of bounds'	)






						def UpperCAmelCase_				(      self      :      str		,   _A      :      int		,   _A      :      int		,   _A      :      float	)							->    None:







							"""simple docstring"""


							if 0 <= x < self.__height and 0 <= y < self.__width:
								snake_case_		:			Optional[Any]											=	value
							else:
								raise Exception('change_component: indices out of bounds'	)






						def UpperCAmelCase_				(      self      :      Any		,   _A      :      int		,   _A      :      int	)							->    float:







							"""simple docstring"""


							if self.__height != self.__width:
								raise Exception('Matrix is not square'	)
							snake_case_		:			Optional[int]											=	self.__matrix[:x] + self.__matrix[x + 1 :]
							for i in range(len(_A	)	):
								snake_case_		:			Any											=	minor[i][:y] + minor[i][y + 1 :]
							return Matrix(_A		,   self.__width - 1		,   self.__height - 1	).determinant()






						def UpperCAmelCase_				(      self      :      Any		,   _A      :      int		,   _A      :      int	)							->    float:







							"""simple docstring"""


							if self.__height != self.__width:
								raise Exception('Matrix is not square'	)
							if 0 <= x < self.__height and 0 <= y < self.__width:
								return (-1) ** (x + y) * self.minor(_A		,   _A	)
							else:
								raise Exception('Indices out of bounds'	)






						def UpperCAmelCase_				(      self      :      List[str]	)							->    float:







							"""simple docstring"""


							if self.__height != self.__width:
								raise Exception('Matrix is not square'	)
							if self.__height < 1:
								raise Exception('Matrix has no element'	)
							elif self.__height == 1:
								return self.__matrix[0][0]
							elif self.__height == 2:
								return (
								    self.__matrix[0][0] * self.__matrix[1][1]
								    - self.__matrix[0][1] * self.__matrix[1][0]
								)
							else:
								snake_case_		:			str											=	[
								    self.__matrix[0][y] * self.cofactor(0		,   _A	) for y in range(self.__width	)
								]
								return sum(_A	)


def 							SCREAMING_SNAKE_CASE__						(    __a   ):
	snake_case_		:			list[list[float]]											=	[[0] * n for _ in range(__a   )]
	return Matrix(__a   , __a   , __a   )


def 							SCREAMING_SNAKE_CASE__						(    __a   , __a   , __a   , __a   ):
	random.seed(__a   )
	snake_case_		:			list[list[float]]											=	[
	    [random.randint(__a   , __a   ) for _ in range(__a   )] for _ in range(__a   )
	]
	return Matrix(__a   , __a   , __a   )








from __future__ import annotations


def 							SCREAMING_SNAKE_CASE__						(    __a   , __a = None   , __a = None   , __a = False   , ):
	snake_case_		:			int											=	cipher_alphabet or [chr(__a   ) for i in range(97   , 1_23   )]

	# If the argument is None or the user provided an empty dictionary
	if not frequencies_dict:
		# Frequencies of letters in the english language (how much they show up)
		snake_case_		:			Dict											=	{
		    'a': 0.08497,
		    'b': 0.01492,
		    'c': 0.02202,
		    'd': 0.04253,
		    'e': 0.11162,
		    'f': 0.02228,
		    'g': 0.02015,
		    'h': 0.06094,
		    'i': 0.07546,
		    'j': 0.00153,
		    'k': 0.01292,
		    'l': 0.04025,
		    'm': 0.02406,
		    'n': 0.06749,
		    'o': 0.07507,
		    'p': 0.01929,
		    'q': 0.00095,
		    'r': 0.07587,
		    's': 0.06327,
		    't': 0.09356,
		    'u': 0.02758,
		    'v': 0.00978,
		    'w': 0.02560,
		    'x': 0.00150,
		    'y': 0.01994,
		    'z': 0.00077,
		}
	else:
		# Custom frequencies dictionary
		snake_case_		:			int											=	frequencies_dict

	if not case_sensitive:
		snake_case_		:			Optional[Any]											=	ciphertext.lower()

	# Chi squared statistic values
	snake_case_		:			dict[int, tuple[float, str]]											=	{}

	# cycle through all of the shifts
	for shift in range(len(__a   )   ):
		snake_case_		:			int											=	''

		# decrypt the message with the shift
		for letter in ciphertext:
			try:
				# Try to index the letter in the alphabet
				snake_case_		:			List[Any]											=	(alphabet_letters.index(letter.lower()   ) - shift) % len(
				    __a   )
				decrypted_with_shift += (
				    alphabet_letters[new_key].upper()
				    if case_sensitive and letter.isupper()
				    else alphabet_letters[new_key]
				)
			except ValueError:
				# Append the character if it isn't in the alphabet
				decrypted_with_shift += letter

		snake_case_		:			Union[str, Any]											=	0.0

		# Loop through each letter in the decoded message with the shift
		for letter in decrypted_with_shift:
			if case_sensitive:
				snake_case_		:			List[Any]											=	letter.lower()
				if letter in frequencies:
					# Get the amount of times the letter occurs in the message
					snake_case_		:			Optional[Any]											=	decrypted_with_shift.lower().count(__a   )

					# Get the excepcted amount of times the letter should appear based
					# on letter frequencies
					snake_case_		:			Tuple											=	frequencies[letter] * occurrences

					# Complete the chi squared statistic formula
					snake_case_		:			Optional[int]											=	((occurrences - expected) ** 2) / expected

					# Add the margin of error to the total chi squared statistic
					chi_squared_statistic += chi_letter_value
			else:
				if letter.lower() in frequencies:
					# Get the amount of times the letter occurs in the message
					snake_case_		:			Any											=	decrypted_with_shift.count(__a   )

					# Get the excepcted amount of times the letter should appear based
					# on letter frequencies
					snake_case_		:			List[str]											=	frequencies[letter] * occurrences

					# Complete the chi squared statistic formula
					snake_case_		:			Optional[Any]											=	((occurrences - expected) ** 2) / expected

					# Add the margin of error to the total chi squared statistic
					chi_squared_statistic += chi_letter_value

        # Add the data to the chi_squared_statistic_values dictionary
		snake_case_		:			Any											=	(
		    chi_squared_statistic,
		    decrypted_with_shift,
		)

	# Get the most likely cipher by finding the cipher with the smallest chi squared
	# statistic
	def chi_squared_statistic_values_sorting_key(__a   ) -> tuple[float, str]:
		return chi_squared_statistic_values[key]

	snake_case_		:			int											=	min(
	    __a   , key=__a   , )

	# Get all the data from the most likely cipher (key, decoded message)
	(
	    (
	    snake_case_
	)						,(
	    snake_case_
	)						,
	)		:			str											=	chi_squared_statistic_values[most_likely_cipher]

	# Return the data on the most likely shift
	return (
	    most_likely_cipher,
	    most_likely_cipher_chi_squared_value,
	    decoded_most_likely_cipher,
	)

