
import mpmath  # for roots of unity
import numpy as np




class    SCREAMING_SNAKE_CASE__     :





	'''simple docstring'''



	def __init__(  self	:    Optional[int]			,  lowercase	:    str=None			,  lowercase	:    Optional[int]=None	):


				'''simple docstring'''


				_snake_case		=			list(poly_a or [0]	)[:]
				_snake_case		=			list(poly_b or [0]	)[:]

				# Remove leading zero coefficients
				while self.polyA[-1] == 0:
							self.polyA.pop()
				_snake_case		=			len(self.polyA	)

				while self.polyB[-1] == 0:
							self.polyB.pop()
				_snake_case		=			len(self.polyB	)

				# Add 0 to make lengths equal a power of 2
				_snake_case		=			int(
				    2 ** np.ceil(np.loga(len(self.polyA	) + len(self.polyB	) - 1	)	)	)

				while len(self.polyA	) < self.c_max_length:
							self.polyA.append(0	)
				while len(self.polyB	) < self.c_max_length:
							self.polyB.append(0	)
				# A complex root used for the fourier transform
				_snake_case		=			complex(mpmath.root(x=1			,  n=self.c_max_length			,  k=1	)	)

				# The product
				_snake_case		=			self.__multiply()



	def  A							(  self	:    Optional[int]			,  lowercase	:    List[Any]	):


				'''simple docstring'''


				_snake_case		=			[[x] for x in self.polyA] if which == 'A' else [[x] for x in self.polyB]
				# Corner case
				if len(lowercase	) <= 1:
							return dft[0]
				#
				_snake_case		=			self.c_max_length // 2
				while next_ncol > 0:
							_snake_case		=			[[] for i in range(lowercase	)]
							_snake_case		=			self.root**next_ncol

							# First half of next step
							_snake_case		=			1
							for j in range(self.c_max_length // (next_ncol * 2)	):
										for i in range(lowercase	):
													new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]	)
										current_root *= root
							# Second half of next step
							_snake_case		=			1
							for j in range(self.c_max_length // (next_ncol * 2)	):
										for i in range(lowercase	):
													new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]	)
										current_root *= root
							# Update
							_snake_case		=			new_dft
							_snake_case		=			next_ncol // 2
				return dft[0]



	def  A							(  self	:    Union[str, Any]	):


				'''simple docstring'''


				_snake_case		=			self.__dft('A'	)
				_snake_case		=			self.__dft('B'	)
				_snake_case		=			[[dft_a[i] * dft_b[i] for i in range(self.c_max_length	)]]
				del dft_a
				del dft_b

				# Corner Case
				if len(inverce_c[0]	) <= 1:
							return inverce_c[0]
				# Inverse DFT
				_snake_case		=			2
				while next_ncol <= self.c_max_length:
							_snake_case		=			[[] for i in range(lowercase	)]
							_snake_case		=			self.root ** (next_ncol // 2)
							_snake_case		=			1
							# First half of next step
							for j in range(self.c_max_length // next_ncol	):
										for i in range(next_ncol // 2	):
													# Even positions
													new_inverse_c[i].append(
													    (
													        inverce_c[i][j]
													        + inverce_c[i][j + self.c_max_length // next_ncol]
													    )
													    / 2	)
													# Odd positions
													new_inverse_c[i + next_ncol // 2].append(
													    (
													        inverce_c[i][j]
													        - inverce_c[i][j + self.c_max_length // next_ncol]
													    )
													    / (2 * current_root)	)
										current_root *= root
							# Update
							_snake_case		=			new_inverse_c
							next_ncol *= 2
				# Unpack
				_snake_case		=			[round(x[0].real			,  8	) + round(x[0].imag			,  8	) * 1j for x in inverce_c]

				# Remove leading 0's
				while inverce_c[-1] == 0:
							inverce_c.pop()
				return inverce_c





	def __str__(  self	:    Optional[Any]	):


				'''simple docstring'''


				_snake_case		=			'A = ' + ' + '.join(
				    f'''{coef}*x^{i}''' for coef, i in enumerate(self.polyA[: self.len_A]	)	)
				_snake_case		=			'B = ' + ' + '.join(
				    f'''{coef}*x^{i}''' for coef, i in enumerate(self.polyB[: self.len_B]	)	)
				_snake_case		=			'A*B = ' + ' + '.join(
				    f'''{coef}*x^{i}''' for coef, i in enumerate(self.product	)	)

				return f'''{a}\n{b}\n{c}'''


# Unit tests
if __name__ == "__main__":
			import doctest

			doctest.testmod()

_lowerCamelCase       :				int       =			[4, 1, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5]
_lowerCamelCase       :				str       =			[3, 7, 7, 4, 2, 6, 4, 1, 5, 3, 7, 5]
_lowerCamelCase       :				List[str]       =			{
    0: '''Sunday''',
    1: '''Monday''',
    2: '''Tuesday''',
    3: '''Wednesday''',
    4: '''Thursday''',
    5: '''Friday''',
    6: '''Saturday''',
}






def        a_		(       __lowercase   :	int       ,					__lowercase   :	int       ,					__lowercase   :	int ) ->  str:
			assert len(str(__lowercase ) ) > 2, "year should be in YYYY format"
			assert 1 <= month <= 12, "month should be between 1 to 12"
			assert 1 <= day <= 31, "day should be between 1 to 31"

			# Doomsday algorithm:
			_snake_case		=			year // 100
			_snake_case		=			(5 * (century % 4) + 2) % 7
			_snake_case		=			year % 100
			_snake_case		=			centurian % 12
			_snake_case		=			(
			    (centurian // 12) + centurian_m + (centurian_m // 4) + century_anchor
			) % 7
			_snake_case		=			(
			    DOOMSDAY_NOT_LEAP[month - 1]
			    if (year % 4 != 0) or (centurian == 0 and (year % 400) == 0)
			    else DOOMSDAY_LEAP[month - 1]
			)
			_snake_case		=			(dooms_day + day - day_anchor) % 7
			return WEEK_DAY_NAMES[week_day]


if __name__ == "__main__":
			import doctest

			doctest.testmod()