


from __future__ import annotations

from collections import deque

class 		__a				:
		def __init__(      self      ,   _SCREAMING_SNAKE_CASE						)			->	Optional[int]:




									"""simple docstring"""





									_UpperCAmelCase					=      []
									self.adlist.append(
									    {'value': '', 'next_states': [], 'fail_state': 0, 'output': []}						)

									for keyword in keywords:
																self.add_keyword(_SCREAMING_SNAKE_CASE						)
									self.set_fail_transitions()
		def      UpperCAmelCase__    (      self      ,   _SCREAMING_SNAKE_CASE      ,   _SCREAMING_SNAKE_CASE						)			->	int | None:




									"""simple docstring"""





									for state in self.adlist[current_state]["next_states"]:
																if char == self.adlist[state]["value"]:
																							return state
									return None
		def      UpperCAmelCase__    (      self      ,   _SCREAMING_SNAKE_CASE						)			->	None:




									"""simple docstring"""





									_UpperCAmelCase					=      0
									for character in keyword:
																_UpperCAmelCase					=      self.find_next_state(_SCREAMING_SNAKE_CASE      ,   _SCREAMING_SNAKE_CASE						)
																if next_state is None:
																							self.adlist.append(
																							    {
																							        'value': character,
																							        'next_states': [],
																							        'fail_state': 0,
																							        'output': [],
																							    }						)
																							self.adlist[current_state]["next_states"].append(len(self.adlist						) - 1						)
																							_UpperCAmelCase					=      len(self.adlist						) - 1
																else:
																							_UpperCAmelCase					=      next_state
									self.adlist[current_state]["output"].append(_SCREAMING_SNAKE_CASE						)
		def      UpperCAmelCase__    (      self						)			->	None:




									"""simple docstring"""





									_UpperCAmelCase					=      deque()
									for node in self.adlist[0]["next_states"]:
																q.append(_SCREAMING_SNAKE_CASE						)
																_UpperCAmelCase					=      0
									while q:
																_UpperCAmelCase					=      q.popleft()
																for child in self.adlist[r]["next_states"]:
																							q.append(_SCREAMING_SNAKE_CASE						)
																							_UpperCAmelCase					=      self.adlist[r]['fail_state']
																							while (
																							    self.find_next_state(_SCREAMING_SNAKE_CASE      ,   self.adlist[child]['value']						) is None
																							    and state != 0
																							):
																														_UpperCAmelCase					=      self.adlist[state]['fail_state']
																							_UpperCAmelCase					=      self.find_next_state(
																							    _SCREAMING_SNAKE_CASE      ,   self.adlist[child]['value']						)
																							if self.adlist[child]["fail_state"] is None:
																														_UpperCAmelCase					=      0
																							_UpperCAmelCase					=      (
																							    self.adlist[child]['output']
																							    + self.adlist[self.adlist[child]['fail_state']]['output']
																							)






		def      UpperCAmelCase__    (      self      ,   _SCREAMING_SNAKE_CASE						)			->	dict[str, list[int]]:




									"""simple docstring"""





									_UpperCAmelCase					=      {}  # returns a dict with keywords and list of its occurrences
									_UpperCAmelCase					=      0
									for i in range(len(_SCREAMING_SNAKE_CASE						)						):
																while (
																    self.find_next_state(_SCREAMING_SNAKE_CASE      ,   string[i]						) is None
																    and current_state != 0
																):
																							_UpperCAmelCase					=      self.adlist[current_state]['fail_state']
																_UpperCAmelCase					=      self.find_next_state(_SCREAMING_SNAKE_CASE      ,   string[i]						)
																if next_state is None:
																							_UpperCAmelCase					=      0
																else:
																							_UpperCAmelCase					=      next_state
																							for key in self.adlist[current_state]["output"]:
																														if key not in result:
																																					_UpperCAmelCase					=      []
																														result[key].append(i - len(_SCREAMING_SNAKE_CASE						) + 1						)
									return result


if __name__ == "__main__":
		import doctest

		doctest.testmod()




def 	lowerCAmelCase__			(      a__:		int	)  ->		None:


							'''simple docstring'''





							_UpperCAmelCase					=      generate_pascal_triangle(a__	)
							for row_idx in range(a__	):
														# 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__			(      a__:		int	)  ->		list[list[int]]:


							'''simple docstring'''





							if not isinstance(a__      ,  a__	):
														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'	)

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

def 	lowerCAmelCase__			(      a__:		list[list[int]]      ,  a__:		int	)  ->		list[int]:


							'''simple docstring'''





							_UpperCAmelCase					=      [-1] * (current_row_idx + 1)
							# first and last elements of current row are equal to 1
							_UpperCAmelCase		,	_UpperCAmelCase					=      1, 1
							for current_col_idx in range(1      ,  a__	):
														calculate_current_element(
														    a__      ,  a__      ,  a__      ,  a__	)
							return current_row

def 	lowerCAmelCase__			(      a__:		list[list[int]]      ,  a__:		list[int]      ,  a__:		int      ,  a__:		int      ,  )  ->		None:


							'''simple docstring'''





							_UpperCAmelCase					=      triangle[current_row_idx - 1][current_col_idx - 1]
							_UpperCAmelCase					=      triangle[current_row_idx - 1][current_col_idx]
							_UpperCAmelCase					=      above_to_left_elt + above_to_right_elt

def 	lowerCAmelCase__			(      a__:		int	)  ->		list[list[int]]:


							'''simple docstring'''





							if not isinstance(a__      ,  a__	):
														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'	)

							_UpperCAmelCase					=      [[1]]

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

							return result

def 	lowerCAmelCase__			(      )  ->		None:


							'''simple docstring'''





							from collections.abc import Callable
							from timeit import timeit

							def benchmark_a_function(a__:		Callable      ,  a__:		int	) -> None:
														_UpperCAmelCase					=      F'''{func.__name__}({value})'''
														_UpperCAmelCase					=      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(1_5	):  # (1, 7, 14):
														for func in (generate_pascal_triangle, generate_pascal_triangle_optimized):
																					benchmark_a_function(a__      ,  a__	)
														print()


if __name__ == "__main__":
		import doctest

		doctest.testmod()
		benchmark()
