How to resolve the algorithm Pascal's triangle step by step in the Python programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Pascal's triangle step by step in the Python programming language

Table of Contents

Problem Statement

Pascal's triangle is an arithmetic and geometric figure often associated with the name of Blaise Pascal, but also studied centuries earlier in India, Persia, China and elsewhere. Its first few rows look like this: where each element of each row is either 1 or the sum of the two elements right above it. For example, the next row of the triangle would be: So the triangle now looks like this: Each row   n   (starting with row   0   at the top) shows the coefficients of the binomial expansion of   (x + y)n.

Write a function that prints out the first   n   rows of the triangle   (with   f(1)   yielding the row consisting of only the element 1). This can be done either by summing elements from the previous rows or using a binary coefficient or combination function. Behavior for   n ≤ 0   does not need to be uniform, but should be noted.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Pascal's triangle step by step in the Python programming language

First implementation The first implementation of Pascal's triangle in Python uses a recursive approach to generate each row of the triangle.

The pascal function takes a single argument, n, which specifies the number of rows to generate. The function returns a list of lists, where each inner list represents a row of the triangle.

The function starts by initializing a variable called row to a list containing a single element, 1. This represents the first row of the triangle. The function also initializes a variable called k to a list containing a single element, 0. This represents the previous row of the triangle.

The function then iterates over a range of n values, starting from 0. For each value of n, the function prints the current row of the triangle and then updates the row and k variables to represent the next row of the triangle.

The function updates the row variable by zipping together the current row and the previous row, and then adding the corresponding elements from each row. This creates a new row that is one element wider than the previous row.

The function updates the k variable by setting it equal to the current row. This ensures that the next row of the triangle will be calculated correctly.

The pascal function returns True if n is greater than or equal to 1, and False if n is less than 1. This allows the calling function to determine whether or not the function was successful in generating the triangle.

Second implementation The second implementation of Pascal's triangle in Python uses a functional approach to generate each row of the triangle.

The pascal function takes a single argument, n, which specifies the number of rows to generate. The function returns a generator object that yields each row of the triangle as a list.

The function starts by defining a nested function called nextrow. This function takes two arguments: a list representing the current row of the triangle and an integer representing the current row number. The function returns a new list representing the next row of the triangle.

The nextrow function calculates the next row of the triangle by adding the corresponding elements from the current row and the previous row. This creates a new row that is one element wider than the previous row.

The pascal function then uses the scan function to apply the nextrow function to a sequence of integers. This creates a generator object that yields each row of the triangle as a list.

The scan function takes three arguments: a function, a sequence of values, and an initial value. The function applies the given function to each value in the sequence, and returns a generator object that yields the results of each application. The initial value is used as the first argument to the function for the first application.

The pascal function returns the generator object created by the scan function. This allows the calling function to iterate over each row of the triangle as a list.

Third implementation The third implementation of Pascal's triangle in Python uses a more concise and elegant functional approach to generate each row of the triangle.

The pascalTriangle function is a generator function that yields each row of Pascal's triangle as a list. The function uses the accumulate function to calculate each row of the triangle by adding the corresponding elements from the previous row.

The accumulate function takes two arguments: a sequence of values and a function. The function applies the given function to each pair of adjacent values in the sequence, and returns a generator object that yields the results of each application. The first value in the sequence is used as the first argument to the function for the first application.

The pascalTriangle function returns the generator object created by the accumulate function. This allows the calling function to iterate over each row of the triangle as a list.

The finitePascalRows function is a wrapper function that takes a single argument, n, and returns a list of the first n rows of Pascal's triangle. The function uses the islice function to take the first n elements from the generator object returned by the pascalTriangle function.

Tests The main function is the entry point for the program. The function tests the two different implementations of Pascal's triangle by generating and printing the first 7 rows of each implementation.

The showPascal function is a helper function that converts a list of Pascal's triangle rows into a string representation. The function uses the align function to align each row of the triangle to the center of the screen.

The align function takes three arguments: a width, a character, and a string. The function returns a new string that is the original string padded with the given character to the approximate center of the screen, fitting in but not truncated to the given width.

The center function is a helper function that takes three arguments: a width, a character, and a string. The function returns a new string that is the original string padded with the given character to the exact center of the screen, fitting in and truncated to the given width.

The iterate function is a helper function that takes a function and a value, and returns a generator object that yields an infinite list of repeated applications of the function to the value.

Results The output of the program is as follows:

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1

Source code in the python programming language

def pascal(n):
   """Prints out n rows of Pascal's triangle.
   It returns False for failure and True for success."""
   row = [1]
   k = [0]
   for x in range(max(n,0)):
      print row
      row=[l+r for l,r in zip(row+k,k+row)]
   return n>=1

def scan(op, seq, it):
  a = []
  result = it
  a.append(it)
  for x in seq:
    result = op(result, x)
    a.append(result)
  return a

def pascal(n):
    def nextrow(row, x):
        return [l+r for l,r in zip(row+[0,],[0,]+row)]

    return scan(nextrow, range(n-1), [1,])

for row in pascal(4):
    print(row)

'''Pascal's triangle'''

from itertools import (accumulate, chain, islice)
from operator import (add)


# nextPascal :: [Int] -> [Int]
def nextPascal(xs):
    '''A row of Pascal's triangle
       derived from a preceding row.'''
    return list(
        map(add, [0] + xs, xs + [0])
    )


# pascalTriangle :: Generator [[Int]]
def pascalTriangle():
    '''A non-finite stream of
       Pascal's triangle rows.'''
    return iterate(nextPascal)([1])


# finitePascalRows :: Int -> [[Int]]
def finitePascalRows(n):
    '''The first n rows of Pascal's triangle.'''
    return accumulate(
        chain(
            [[1]], range(1, n)
        ),
        lambda a, _: nextPascal(a)
    )


# ------------------------ TESTS -------------------------
# main :: IO ()
def main():
    '''Test of two different approaches:
        - taking from a non-finite stream of rows,
        - or constructing a finite list of rows.'''
    print('\n'.join(map(
        showPascal,
        [
            islice(
                pascalTriangle(),       # Non finite,
                7
            ),
            finitePascalRows(7)         # finite.
        ]
    )))


# showPascal :: [[Int]] -> String
def showPascal(xs):
    '''Stringification of a list of
       Pascal triangle rows.'''
    ys = list(xs)

    def align(w):
        return lambda ns: center(w)(
            ' '
        )('   '.join(map(str, ns)))

    w = len('   '.join((map(str, ys[-1]))))
    return '\n'.join(map(align(w), ys))


# ----------------------- GENERIC ------------------------

# center :: Int -> Char -> String -> String
def center(n):
    '''String s padded with c to approximate centre,
       fitting in but not truncated to width n.'''
    def go(c, s):
        qr = divmod(n - len(s), 2)
        q = qr[0]
        return (q * c) + s + ((q + qr[1]) * c)

    return lambda c: lambda s: go(c, s)


# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
    '''An infinite list of repeated
       applications of f to x.
    '''
    def go(x):
        v = x
        while True:
            yield v
            v = f(v)

    return go


# MAIN ---
if __name__ == '__main__':
    main()

  

You may also check:How to resolve the algorithm Infinity step by step in the C++ programming language
You may also check:How to resolve the algorithm Break OO privacy step by step in the Ada programming language
You may also check:How to resolve the algorithm Copy a string step by step in the Aime programming language
You may also check:How to resolve the algorithm Case-sensitivity of identifiers step by step in the RPL programming language
You may also check:How to resolve the algorithm Symmetric difference step by step in the C programming language