1

I am asked to write a recursion for Pascal's triangle, with tuples. This is my code:

def pascal(n):
    if n == 1:
        return (1,)
    if n == 2:
        return ((1,),(1,1))
    else:
        new_row = ()
        for i in range(-1, n-1):
            if i == -1:
                new_row = new_row + (1,)
            elif i == n - 1:
                new_row = new_row + (1,)
            else: 
                a = pascal(n-1)[n-2][i] + pascal(n-2)[n-1][i+1]
                new_row = new_row + (a,)
        return pascal(n-1), new_row

I am getting an error that says tuple index out of range if I call pascal(3) or higher.

This is the trace output:

Traceback (most recent call last):
  File "tup.py", line 19, in <module>
    print pascal(3)
  File "tup.py", line 15, in pascal
    a = pascal(n-1)[n-2][i] + pascal(n-2)[n-1][i+1]
IndexError: tuple index out of range

Appreciate any kind assistance, thank you!

Stefan M
  • 868
  • 6
  • 17
aijnij
  • 91
  • 2
  • 10
  • can you please post the full trace back? – Ma0 Feb 15 '18 at 12:00
  • could you please post the input that you are using? – Nazim Kerimbekov Feb 15 '18 at 12:01
  • Try debugging your input. Especially, after the `else:`, print out the values for `n` and `i`. That will you give you the information where you're out of range. If that doesn't give you enough information, print out the information on the tuples itself (size, content, etc.). – Stefan M Feb 15 '18 at 12:01
  • I would assume that your second `if`statement should probably be an `elif`( n can't be equal to 2 and 1 at the same time). This might solve the problem! – Nazim Kerimbekov Feb 15 '18 at 12:04
  • pascal(3) Traceback (most recent call last): File "", line 1, in pascal(3) File "", line 14, in pascal a = pascal(n-1)[n-2][i] + pascal(n-2)[n-1][i+1] IndexError: tuple index out of range – aijnij Feb 15 '18 at 12:10

1 Answers1

4

The following will work. Loop from 0 to n-2 (exclusive) on the previous row:

def pascal(n):
    if n == 1:  # one base case is enough
        return ((1,),)  # return tuple of tuples to be consistent
    prev = pascal(n-1)
    new_row = [1] + [prev[-1][i]+prev[-1][i+1] for i in range(n-2)] + [1]
    return prev + tuple(new_row)

>>> pascal(2)
((1,), (1, 1))
>>> pascal(3)
((1,), (1, 1), (1, 2, 1))
>>> pascal(4)
((1,), (1, 1), (1, 2, 1), (1, 3, 3, 1))

Explanation: The n-th row has n elements, 2 of which are 1. Thus n-2 of the elements are formed by appropriate sums in the loop, hence the range.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • thanks for the help, but would there be a way without having to use the tuple() function? – aijnij Feb 15 '18 at 12:21
  • Well, you can keep concatenating the literals as you did before, but that is even worse performance wise. This is the mere `tuple` constructor that is passed an appropriate generator expression. – user2390182 Feb 15 '18 at 12:23
  • @LinJinjia SInce they are immutable, tuples are not ideal to build incrementally. If anything, you should keep `append`ing to a list and turn it into a tuple in the end. – user2390182 Feb 15 '18 at 12:28