




import heapq as hq
import math
from collections.abc import Iterator






class  _lowerCAmelCase     :

      def __init__(   self      ,				__UpperCAmelCase		):
        lowerCAmelCase__				:  Optional[int]		       =     str(id_		)
        lowerCAmelCase__				:  Any		       =     None
        lowerCAmelCase__				:  str		       =     None
        lowerCAmelCase__				:  Any		       =     []
        lowerCAmelCase__				:  Optional[int]		       =     {}  # {vertex:distance}

      def __lt__(   self      ,				__UpperCAmelCase		):
        return self.key < other.key

      def __repr__(   self		):
        return self.id

      def 	__magic_name__(   self      ,				__UpperCAmelCase		):
        self.neighbors.append(__UpperCAmelCase		)







      def 	__magic_name__(   self      ,				__UpperCAmelCase      ,				__UpperCAmelCase		):
        lowerCAmelCase__				:  Union[str, Any]		       =     weight



def      __lowerCAmelCase			(					UpperCamelCase	,      UpperCamelCase	,      UpperCamelCase	,      UpperCamelCase      )     ->	Optional[Any]:
  # add the neighbors:
  graph[a - 1].add_neighbor(graph[b - 1]      )
  graph[b - 1].add_neighbor(graph[a - 1]      )
  # add the edges:
  graph[a - 1].add_edge(graph[b - 1]	,      UpperCamelCase      )
  graph[b - 1].add_edge(graph[a - 1]	,      UpperCamelCase      )



def      __lowerCAmelCase			(					UpperCamelCase	,      UpperCamelCase      )     ->	list:
  lowerCAmelCase__				:  List[Any]		       =     []
  for u in graph:
    lowerCAmelCase__				:  Tuple		       =     math.inf
    lowerCAmelCase__				:  Optional[Any]		       =     None
  lowerCAmelCase__				:  Any		       =     0
  lowerCAmelCase__				:  int		       =     graph[:]
  while q:
    lowerCAmelCase__				:  List[str]		       =     min(UpperCamelCase      )
    q.remove(UpperCamelCase      )
    for v in u.neighbors:
      if (v in q) and (u.edges[v.id] < v.key):
        lowerCAmelCase__				:  List[str]		       =     u
        lowerCAmelCase__				:  Optional[int]		       =     u.edges[v.id]
  for i in range(1	,      len(UpperCamelCase      )      ):
    a.append((int(graph[i].id      ) + 1, int(graph[i].pi.id      ) + 1)      )
  return a



def      __lowerCAmelCase			(					UpperCamelCase	,      UpperCamelCase      )     ->	Iterator[tuple]:
  for u in graph:
    lowerCAmelCase__				:  List[Any]		       =     math.inf
    lowerCAmelCase__				:  Dict		       =     None
  lowerCAmelCase__				:  Union[str, Any]		       =     0

  lowerCAmelCase__				:  int		       =     list(UpperCamelCase      )
  hq.heapify(UpperCamelCase      )

  while h:
    lowerCAmelCase__				:  Optional[Any]		       =     hq.heappop(UpperCamelCase      )
    for v in u.neighbors:
      if (v in h) and (u.edges[v.id] < v.key):
        lowerCAmelCase__				:  Tuple		       =     u
        lowerCAmelCase__				:  Any		       =     u.edges[v.id]
        hq.heapify(UpperCamelCase      )

  for i in range(1	,      len(UpperCamelCase      )      ):
    yield (int(graph[i].id      ) + 1, int(graph[i].pi.id      ) + 1)



def      __lowerCAmelCase			(					)     ->	None:
  pass


if __name__ == "__main__":
     import doctest

     doctest.testmod()







def      __lowerCAmelCase			(					UpperCamelCase      )     ->	None:
  lowerCAmelCase__				:  Dict		       =     generate_pascal_triangle(UpperCamelCase      )
  for row_idx in range(UpperCamelCase      ):
    # 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			(					UpperCamelCase      )     ->	list[list[int]]:

  if not isinstance(UpperCamelCase	,      UpperCamelCase      ):
    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__				:  list[list[int]]		       =     []
  for current_row_idx in range(UpperCamelCase      ):
    lowerCAmelCase__				:  List[str]		       =     populate_current_row(UpperCamelCase	,      UpperCamelCase      )
    triangle.append(UpperCamelCase      )
  return triangle



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



def      __lowerCAmelCase			(					UpperCamelCase	,      UpperCamelCase	,      UpperCamelCase	,      UpperCamelCase	,      )     ->	None:
  lowerCAmelCase__				:  Optional[int]		       =     triangle[current_row_idx - 1][current_col_idx - 1]
  lowerCAmelCase__				:  List[str]		       =     triangle[current_row_idx - 1][current_col_idx]
  lowerCAmelCase__				:  List[Any]		       =     above_to_left_elt + above_to_right_elt



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

  if not isinstance(UpperCamelCase	,      UpperCamelCase      ):
    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__				:  list[list[int]]		       =     [[1]]

  for row_index in range(1	,      UpperCamelCase      ):
    lowerCAmelCase__				:  Optional[int]		       =     [0] + result[-1] + [0]
    lowerCAmelCase__				:  List[str]		       =     row_index + 1
    # Calculate the number of distinct elements in a row
    lowerCAmelCase__				:  Tuple		       =     sum(divmod(UpperCamelCase	,      2      )      )
    lowerCAmelCase__				:  Tuple		       =     [
        temp_row[i - 1] + temp_row[i] for i in range(1	,      distinct_elements + 1      )
    ]
    lowerCAmelCase__				:  int		       =     row_first_half[: (row_index + 1) // 2]
    row_second_half.reverse()
    lowerCAmelCase__				:  Dict		       =     row_first_half + row_second_half
    result.append(UpperCamelCase      )

  return result



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

  def benchmark_a_function(UpperCamelCase	,      UpperCamelCase      ) -> None:
    lowerCAmelCase__				:  Tuple		       =     F"""{func.__name__}({value})"""
    lowerCAmelCase__				:  Dict		       =     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(UpperCamelCase	,      UpperCamelCase      )
    print()


if __name__ == "__main__":
     import doctest

     doctest.testmod()
     benchmark()

