Skip to content

Commit fecbf59

Browse files
TechFreak107pre-commit-ci[bot]cclauss
authored
Modified 'pascal_triangle.py' program (TheAlgorithms#7901)
* Added pascals_triangle.py program to maths directory * Deleted 'pascals_triangle.py' because of duplication. Added a optimized function to generate pascal's triangle to 'pascal_triangle.py' program. Added some aadditional doctests to the existing function. Added some type check functionality to the existing function. * Modified type check hints in 'generate_pascal_triangle_optimized' function' q * Modified 'pascal_triangle' prgram * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update pascal_triangle.py Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent a31edd4 commit fecbf59

File tree

1 file changed

+101
-8
lines changed

1 file changed

+101
-8
lines changed

other/pascal_triangle.py

+101-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
"""
2-
This implementation demonstrates how to generate the
3-
elements of a Pascal's triangle. The element having
4-
a row index of r and column index of c can be derived
5-
as follows:
2+
This implementation demonstrates how to generate the elements of a Pascal's triangle.
3+
The element havingva row index of r and column index of c can be derivedvas follows:
64
triangle[r][c] = triangle[r-1][c-1]+triangle[r-1][c]
7-
What is Pascal's triangle?
8-
- It is a triangular array containing binomial coefficients.
9-
Refer to (https://en.wikipedia.org/wiki/Pascal%27s_triangle)
10-
for more info about this triangle.
5+
6+
A Pascal's triangle is a triangular array containing binomial coefficients.
7+
https://en.wikipedia.org/wiki/Pascal%27s_triangle
118
"""
129

1310

@@ -38,6 +35,8 @@ def print_pascal_triangle(num_rows: int) -> None:
3835
def generate_pascal_triangle(num_rows: int) -> list[list[int]]:
3936
"""
4037
Create Pascal's triangle for different number of rows
38+
>>> generate_pascal_triangle(0)
39+
[]
4140
>>> generate_pascal_triangle(1)
4241
[[1]]
4342
>>> generate_pascal_triangle(2)
@@ -48,7 +47,26 @@ def generate_pascal_triangle(num_rows: int) -> list[list[int]]:
4847
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]
4948
>>> generate_pascal_triangle(5)
5049
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
50+
>>> generate_pascal_triangle(-5)
51+
Traceback (most recent call last):
52+
...
53+
ValueError: The input value of 'num_rows' should be greater than or equal to 0
54+
>>> generate_pascal_triangle(7.89)
55+
Traceback (most recent call last):
56+
...
57+
TypeError: The input value of 'num_rows' should be 'int'
5158
"""
59+
60+
if not isinstance(num_rows, int):
61+
raise TypeError("The input value of 'num_rows' should be 'int'")
62+
63+
if num_rows == 0:
64+
return []
65+
elif num_rows < 0:
66+
raise ValueError(
67+
"The input value of 'num_rows' should be greater than or equal to 0"
68+
)
69+
5270
triangle: list[list[int]] = []
5371
for current_row_idx in range(num_rows):
5472
current_row = populate_current_row(triangle, current_row_idx)
@@ -90,7 +108,82 @@ def calculate_current_element(
90108
current_row[current_col_idx] = above_to_left_elt + above_to_right_elt
91109

92110

111+
def generate_pascal_triangle_optimized(num_rows: int) -> list[list[int]]:
112+
"""
113+
This function returns a matrix representing the corresponding pascal's triangle
114+
according to the given input of number of rows of Pascal's triangle to be generated.
115+
It reduces the operations done to generate a row by half
116+
by eliminating redundant calculations.
117+
118+
:param num_rows: Integer specifying the number of rows in the Pascal's triangle
119+
:return: 2-D List (matrix) representing the Pascal's triangle
120+
121+
Return the Pascal's triangle of given rows
122+
>>> generate_pascal_triangle_optimized(3)
123+
[[1], [1, 1], [1, 2, 1]]
124+
>>> generate_pascal_triangle_optimized(1)
125+
[[1]]
126+
>>> generate_pascal_triangle_optimized(0)
127+
[]
128+
>>> generate_pascal_triangle_optimized(-5)
129+
Traceback (most recent call last):
130+
...
131+
ValueError: The input value of 'num_rows' should be greater than or equal to 0
132+
>>> generate_pascal_triangle_optimized(7.89)
133+
Traceback (most recent call last):
134+
...
135+
TypeError: The input value of 'num_rows' should be 'int'
136+
"""
137+
138+
if not isinstance(num_rows, int):
139+
raise TypeError("The input value of 'num_rows' should be 'int'")
140+
141+
if num_rows == 0:
142+
return []
143+
elif num_rows < 0:
144+
raise ValueError(
145+
"The input value of 'num_rows' should be greater than or equal to 0"
146+
)
147+
148+
result: list[list[int]] = [[1]]
149+
150+
for row_index in range(1, num_rows):
151+
temp_row = [0] + result[-1] + [0]
152+
row_length = row_index + 1
153+
# Calculate the number of distinct elements in a row
154+
distinct_elements = sum(divmod(row_length, 2))
155+
row_first_half = [
156+
temp_row[i - 1] + temp_row[i] for i in range(1, distinct_elements + 1)
157+
]
158+
row_second_half = row_first_half[: (row_index + 1) // 2]
159+
row_second_half.reverse()
160+
row = row_first_half + row_second_half
161+
result.append(row)
162+
163+
return result
164+
165+
166+
def benchmark() -> None:
167+
"""
168+
Benchmark multiple functions, with three different length int values.
169+
"""
170+
from collections.abc import Callable
171+
from timeit import timeit
172+
173+
def benchmark_a_function(func: Callable, value: int) -> None:
174+
call = f"{func.__name__}({value})"
175+
timing = timeit(f"__main__.{call}", setup="import __main__")
176+
# print(f"{call:38} = {func(value)} -- {timing:.4f} seconds")
177+
print(f"{call:38} -- {timing:.4f} seconds")
178+
179+
for value in range(15): # (1, 7, 14):
180+
for func in (generate_pascal_triangle, generate_pascal_triangle_optimized):
181+
benchmark_a_function(func, value)
182+
print()
183+
184+
93185
if __name__ == "__main__":
94186
import doctest
95187

96188
doctest.testmod()
189+
benchmark()

0 commit comments

Comments
 (0)