I wrote a number to output the nth row of Pascal's Triangle:
import sys
def nth_row_pascal(n):
def nth_num(i, j):
if i==0:
print("({},{}) determined to be 1".format(i,j))
return 1
if (j == 0) or (j==i):
print("({},{}) determined to be 1".format(i,j))
return 1
print("calculating pascal number: ({},{})".format(i,j))
result=nth_num(i-1, j-1) + nth_num(i-1, j)
print("answer: " + str(result))
return result
result = [nth_num(i, int(n)-1) for i in range(int(n))]
return result
print(nth_row_pascal(sys.argv[1]))
When I run
python pascal.py 4
I get:
python3 pascal.py 4
(0,3) determined to be 1
calculating pascal number: (1,3)
(0,2) determined to be 1
(0,3) determined to be 1
answer: 2
calculating pascal number: (2,3)
calculating pascal number: (1,2)
(0,1) determined to be 1
(0,2) determined to be 1
answer: 2
calculating pascal number: (1,3)
(0,2) determined to be 1
(0,3) determined to be 1
answer: 2
answer: 4
(3,3) determined to be 1
[1, 2, 4, 1]
Why is
answer: 4
popping up?
It seems that the function nth_num
will print out a statement -- either
i,j determined to be 1
or calculating pascal number
...But in this case it goes
answer: 2
(understandable)
answer: 4
(what??)
each time it is executed.
A lot of stuff happens in between the "calculating" and "answer" lines, including other recursive calls! Here's some ASCII art and some extra whitespace to help clear up where exactly that answer: 4
comes from:
(0,3) determined to be 1
calculating pascal number: (1,3) >-----\
(0,2) determined to be 1 |
(0,3) determined to be 1 |
answer: 2 <---------------------------/
calculating pascal number: (2,3) >-----\
|
calculating pascal number: (1,2) >-\ |
(0,1) determined to be 1 | |
(0,2) determined to be 1 | |
answer: 2 <-----------------------/ |
|
calculating pascal number: (1,3) >-\ |
(0,2) determined to be 1 | |
(0,3) determined to be 1 | |
answer: 2 <-----------------------/ |
|
answer: 4 <---------------------------/
(3,3) determined to be 1
When tracing recursive functions to understand how they work it can help to print out the depth of the recursive call, like this:
from typing import List
def nth_row_pascal(arg: str) -> List[int]:
n = int(arg)
def nth_num(i: int, j: int, depth: int) -> int:
indent = " " * depth # for pretty-printing
if i == 0:
print(f"{indent}{(i, j)} determined to be 1")
return 1
if j in {0, i}:
print(f"{indent}{(i, j)} determined to be 1")
return 1
print(f"{indent}calculating pascal number: {(i, j)}")
result = nth_num(i-1, j-1, depth+1) + nth_num(i-1, j, depth+1)
print(f"{indent}answer: {result}")
return result
result = [nth_num(i, n-1, 0) for i in range(n)]
return result
(0, 3) determined to be 1
calculating pascal number: (1, 3)
(0, 2) determined to be 1
(0, 3) determined to be 1
answer: 2
calculating pascal number: (2, 3)
calculating pascal number: (1, 2)
(0, 1) determined to be 1
(0, 2) determined to be 1
answer: 2
calculating pascal number: (1, 3)
(0, 2) determined to be 1
(0, 3) determined to be 1
answer: 2
answer: 4
(3, 3) determined to be 1
[1, 2, 4, 1]