


"""simple docstring"""



import mpmath  # for roots of unity
import numpy as np







class _lowerCAmelCase				:







   def __init__(	self						,	UpperCamelCase__=None						,	UpperCamelCase__=None						)	->		Union[str, Any]:

       '''simple docstring'''




       snake_case    :      str      					=    list(poly_a or [0]						)[:]
       snake_case    :      Any      					=    list(poly_b or [0]						)[:]

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

       while self.polyB[-1] == 0:
           self.polyB.pop()
       snake_case    :      Union[str, Any]      					=    len(self.polyB						)

       # Add 0 to make lengths equal a power of 2
       snake_case    :      str      					=    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    :      int      					=    complex(mpmath.root(x=1						,	n=self.c_max_length						,	k=1						)						)

       # The product
       snake_case    :      int      					=    self.__multiply()







   def  lowerCamelCase		(	self						,	UpperCamelCase__						)	->		List[str]:

       '''simple docstring'''




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

           # First half of next step
           snake_case    :      Dict      					=    1
           for j in range(self.c_max_length // (next_ncol * 2)						):
               for i in range(UpperCamelCase_						):
                   new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]						)
               current_root *= root
           # Second half of next step
           snake_case    :      int      					=    1
           for j in range(self.c_max_length // (next_ncol * 2)						):
               for i in range(UpperCamelCase_						):
                   new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]						)
               current_root *= root
           # Update
           snake_case    :      Optional[Any]      					=    new_dft
           snake_case    :      Union[str, Any]      					=    next_ncol // 2
       return dft[0]







   def  lowerCamelCase		(	self						)	->		Dict:

       '''simple docstring'''




       snake_case    :      Optional[Any]      					=    self.__dft("A"						)
       snake_case    :      Optional[int]      					=    self.__dft("B"						)
       snake_case    :      Any      					=    [[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    :      str      					=    2
       while next_ncol <= self.c_max_length:
           snake_case    :      Union[str, Any]      					=    [[] for i in range(UpperCamelCase_						)]
           snake_case    :      Optional[Any]      					=    self.root ** (next_ncol // 2)
           snake_case    :      Tuple      					=    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    :      Any      					=    new_inverse_c
           next_ncol *= 2
       # Unpack
       snake_case    :      Optional[int]      					=    [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    :      int      					=    '''A = ''' + ''' + '''.join(
           F'{coef}*x^{i}' for coef, i in enumerate(self.polyA[: self.len_A]						)						)
       snake_case    :      str      					=    '''B = ''' + ''' + '''.join(
           F'{coef}*x^{i}' for coef, i in enumerate(self.polyB[: self.len_B]						)						)
       snake_case    :      int      					=    '''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()









"""simple docstring"""





def    _snake_case  (  _snake_case :	list	):

      def merge(_snake_case :	list       ,      _snake_case :	list	) -> list:

            def _merge():
                  while left and right:
                        yield (left if left[0] <= right[0] else right).pop(0	)
                  yield from left
                  yield from right

            return list(_merge()	)

      if len(_snake_case	) <= 1:
            return collection
      lowerCAmelCase    :		Union[str, Any]				=      len(_snake_case	) // 2
      return merge(merge_sort(collection[:mid]	)       ,      merge_sort(collection[mid:]	)	)


if __name__ == "__main__":
 import doctest

 doctest.testmod()
 snake_case__						:   Optional[Any]			 = input('''Enter numbers separated by a comma:\n''').strip()
 snake_case__						:   Union[str, Any]			 = [int(item) for item in user_input.split(''',''')]
 print(*merge_sort(unsorted), sep=''',''')


