Skip to content

Modified 'pascal_triangle.py' program #7901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 31, 2022
Merged
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions other/pascal_triangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def print_pascal_triangle(num_rows: int) -> None:
def generate_pascal_triangle(num_rows: int) -> list[list[int]]:
"""
Create Pascal's triangle for different number of rows
>>> generate_pascal_triangle(0)
[]
>>> generate_pascal_triangle(1)
[[1]]
>>> generate_pascal_triangle(2)
Expand All @@ -48,7 +50,26 @@ def generate_pascal_triangle(num_rows: int) -> list[list[int]]:
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]
>>> generate_pascal_triangle(5)
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
>>> generate_pascal_triangle(-5)
Traceback (most recent call last):
...
ValueError: The input value of 'num_rows' should be greater than or equal to 0
>>> generate_pascal_triangle(7.89)
Traceback (most recent call last):
...
TypeError: The input value of 'num_rows' should be 'int'
"""

if not isinstance(num_rows, int):
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"
)

triangle: list[list[int]] = []
for current_row_idx in range(num_rows):
current_row = populate_current_row(triangle, current_row_idx)
Expand Down Expand Up @@ -90,6 +111,66 @@ def calculate_current_element(
current_row[current_col_idx] = above_to_left_elt + above_to_right_elt


def generate_pascal_triangle_optimized(num_rows: int) -> list[list[int]]:
"""
This function returns a matrix representing the corresponding pascal's triangle
according to the given input of number of rows of Pascal's triangle to be generated.
It reduces the operations done to generate a row by half
by eliminating redundant calculations.

:param num_rows: Integer specifying the number of rows in the Pascal's triangle
:return: 2-D List (matrix) representing the Pascal's triangle

Return the Pascal's triangle of given rows
>>> generate_pascal_triangle_optimized(3)
[[1], [1, 1], [1, 2, 1]]
>>> generate_pascal_triangle_optimized(1)
[[1]]
>>> generate_pascal_triangle_optimized(0)
[]
>>> generate_pascal_triangle_optimized(-5)
Traceback (most recent call last):
...
ValueError: The input value of 'num_rows' should be greater than or equal to 0
>>> generate_pascal_triangle_optimized(7.89)
Traceback (most recent call last):
...
TypeError: The input value of 'num_rows' should be 'int'
"""

if not isinstance(num_rows, int):
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"
)

result: list[list[int]] = [[1]]

for row_index in range(1, num_rows):
temp_row = [0] + result[-1] + [0]
row_length = row_index + 1

# It calculates the number of distinct elements in a row
distinct_elements = (
row_length // 2 if row_length % 2 == 0 else row_length // 2 + 1
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leverage the Python builtin functions:

Suggested change
distinct_elements = (
row_length // 2 if row_length % 2 == 0 else row_length // 2 + 1
)
distinct_elements = sum(divmod(row_length, 2))


row_first_half = [
temp_row[x - 1] + temp_row[x] for x in range(1, distinct_elements + 1)
]
Copy link
Member

@cclauss cclauss Oct 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use i for integers, indexes, etc. Use item for objects in a list. Use x only when space is tight.

Suggested change
row_first_half = [
temp_row[x - 1] + temp_row[x] for x in range(1, distinct_elements + 1)
]
row_first_half = [item + temp_row[i + 1] for i, item in enumerate(temp_row)]


row_second_half = row_first_half[: (row_index + 1) // 2]
row_second_half.reverse()
row = row_first_half + row_second_half
result.append(row)

return result


if __name__ == "__main__":
import doctest

Expand Down