



from __future__ import annotations

from collections.abc import MutableSequence






class 						__a :



	def __init__(						self							:    List[Any]				,	snake_case_							:    int				,	snake_case_							:    MutableSequence[float])->							None:
						if len(snake_case_) != degree + 1:
											raise ValueError(
											    """The number of coefficients should be equal to the degree + 1.""")

						__lowerCAmelCase	   =list(snake_case_)
						__lowerCAmelCase	   =degree



	def __add__(						self							:    int				,	snake_case_							:    Polynomial)->							Polynomial:

						if self.degree > polynomial_a.degree:
											__lowerCAmelCase	   =self.coefficients[:]
											for i in range(polynomial_a.degree + 1):
																coefficients[i] += polynomial_a.coefficients[i]
											return Polynomial(self.degree				,	snake_case_)
						else:
											__lowerCAmelCase	   =polynomial_a.coefficients[:]
											for i in range(self.degree + 1):
																coefficients[i] += self.coefficients[i]
											return Polynomial(polynomial_a.degree				,	snake_case_)



	def __sub__(						self							:    List[str]				,	snake_case_							:    Polynomial)->							Polynomial:
						return self + polynomial_a * Polynomial(0				,	[-1])



	def __neg__(						self							:    Dict)->							Polynomial:
						return Polynomial(self.degree				,	[-c for c in self.coefficients])



	def __mul__(						self							:    Any				,	snake_case_							:    Polynomial)->							Polynomial:
						__lowerCAmelCase	   =[0] * (self.degree + polynomial_a.degree + 1)
						for i in range(self.degree + 1):
											for j in range(polynomial_a.degree + 1):
																coefficients[i + j] += (
																    self.coefficients[i] * polynomial_a.coefficients[j]
																)

						return Polynomial(self.degree + polynomial_a.degree				,	snake_case_)



	def 		UpperCamelCase							(						self							:    List[str]				,	snake_case_							:    int | float)->							int | float:
						__lowerCAmelCase	   =0
						for i in range(self.degree + 1):
											result += self.coefficients[i] * (substitution**i)
						return result



	def __str__(						self							:    Union[str, Any])->							str:
						__lowerCAmelCase	   =""""""
						for i in range(self.degree				,	-1				,	-1):
											if self.coefficients[i] == 0:
																continue
											elif self.coefficients[i] > 0:
																if polynomial:
																					polynomial += " + "
											else:
																polynomial += " - "

											if i == 0:
																polynomial += str(abs(self.coefficients[i]))
											elif i == 1:
																polynomial += str(abs(self.coefficients[i])) + "x"
											else:
																polynomial += str(abs(self.coefficients[i])) + "x^" + str(snake_case_)

						return polynomial



	def __repr__(						self							:    Tuple)->							str:
						return self.__str__()



	def 		UpperCamelCase							(						self							:    Optional[int])->							Polynomial:
						__lowerCAmelCase	   =[0] * self.degree
						for i in range(self.degree):
											__lowerCAmelCase	   =self.coefficients[i + 1] * (i + 1)
						return Polynomial(self.degree - 1				,	snake_case_)



	def 		UpperCamelCase							(						self							:    int				,	snake_case_							:    int | float = 0)->							Polynomial:
						__lowerCAmelCase	   =[0] * (self.degree + 2)
						__lowerCAmelCase	   =constant
						for i in range(self.degree + 1):
											__lowerCAmelCase	   =self.coefficients[i] / (i + 1)
						return Polynomial(self.degree + 1				,	snake_case_)



	def __eq__(						self							:    Union[str, Any]				,	snake_case_							:    object)->							bool:
						if not isinstance(snake_case_				,	snake_case_):
											return False

						if self.degree != polynomial_a.degree:
											return False

						for i in range(self.degree + 1):
											if self.coefficients[i] != polynomial_a.coefficients[i]:
																return False

						return True



	def __ne__(						self							:    List[str]				,	snake_case_							:    object)->							bool:
						return not self.__eq__(snake_case_)









def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						None:
					__lowerCAmelCase	   =generate_pascal_triangle(__lowerCamelCase	)
					for row_idx in range(__lowerCamelCase	):
										# Print left spaces
										for _ in range(num_rows - row_idx - 1	):
															print(end=""" """	)
										# Print row values
										for col_idx in range(row_idx + 1	):
															if col_idx != row_idx:
																				print(triangle[row_idx][col_idx]				,   end=""" """	)
															else:
																				print(triangle[row_idx][col_idx]				,   end=""""""	)
										print()






def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						list[list[int]]:

					if not isinstance(__lowerCamelCase				,   __lowerCamelCase	):
										raise TypeError("""The input value of 'num_rows' should be 'int'"""	)

					if num_rows == 0:
										return []
					elif num_rows < 0:
										raise ValueError(
										    """The input value of 'num_rows' should be greater than or equal to 0"""	)

					__lowerCAmelCase	   =[]
					for current_row_idx in range(__lowerCamelCase	):
										__lowerCAmelCase	   =populate_current_row(__lowerCamelCase				,   __lowerCamelCase	)
										triangle.append(__lowerCamelCase	)
					return triangle






def 					__lowerCAmelCase		(  __lowerCamelCase	:    list[list[int]]				,   __lowerCamelCase	:    int	)  ->						list[int]:
					__lowerCAmelCase	   =[-1] * (current_row_idx + 1)
					# first and last elements of current row are equal to 1
					__lowerCAmelCase   ,	__lowerCAmelCase	   =1, 1
					for current_col_idx in range(1				,   __lowerCamelCase	):
										calculate_current_element(
										    __lowerCamelCase				,   __lowerCamelCase				,   __lowerCamelCase				,   __lowerCamelCase	)
					return current_row






def 					__lowerCAmelCase		(  __lowerCamelCase	:    list[list[int]]				,   __lowerCamelCase	:    list[int]				,   __lowerCamelCase	:    int				,   __lowerCamelCase	:    int				,   )  ->						None:
					__lowerCAmelCase	   =triangle[current_row_idx - 1][current_col_idx - 1]
					__lowerCAmelCase	   =triangle[current_row_idx - 1][current_col_idx]
					__lowerCAmelCase	   =above_to_left_elt + above_to_right_elt






def 					__lowerCAmelCase		(  __lowerCamelCase	:    int	)  ->						list[list[int]]:

					if not isinstance(__lowerCamelCase				,   __lowerCamelCase	):
										raise TypeError("""The input value of 'num_rows' should be 'int'"""	)

					if num_rows == 0:
										return []
					elif num_rows < 0:
										raise ValueError(
										    """The input value of 'num_rows' should be greater than or equal to 0"""	)

					__lowerCAmelCase	   =[[1]]

					for row_index in range(1				,   __lowerCamelCase	):
										__lowerCAmelCase	   =[0] + result[-1] + [0]
										__lowerCAmelCase	   =row_index + 1
										# Calculate the number of distinct elements in a row
										__lowerCAmelCase	   =sum(divmod(__lowerCamelCase				,   2	)	)
										__lowerCAmelCase	   =[
										    temp_row[i - 1] + temp_row[i] for i in range(1				,   distinct_elements + 1	)
										]
										__lowerCAmelCase	   =row_first_half[: (row_index + 1) // 2]
										row_second_half.reverse()
										__lowerCAmelCase	   =row_first_half + row_second_half
										result.append(__lowerCamelCase	)

					return result






def 					__lowerCAmelCase		(  )  ->						None:
					from collections.abc import Callable
					from timeit import timeit

					def benchmark_a_function(__lowerCamelCase	:    Callable				,   __lowerCamelCase	:    int	) -> None:
										__lowerCAmelCase	   =f"""{func.__name__}({value})"""
										__lowerCAmelCase	   =timeit(f"""__main__.{call}"""				,   setup="""import __main__"""	)
										# print(f"{call:38} = {func(value)} -- {timing:.4f} seconds")
										print(f"""{call:38} -- {timing:.4f} seconds"""	)

					for value in range(15	):  # (1, 7, 14):
										for func in (generate_pascal_triangle, generate_pascal_triangle_optimized):
															benchmark_a_function(__lowerCamelCase				,   __lowerCamelCase	)
										print()


if __name__ == "__main__":
				import doctest

				doctest.testmod()
				benchmark()




