python last row recursive pascal triangle - python

I have to create a recursive function pascal(n) that returns the line n of a pascal triangle as a list (so pascal(3) returns [1, 3, 3, 1]).
So far I have
def pascal(n):
if n==1:
return [[1]]
else:
result=pascal(n-1)
row=[1]
last_row=result[-1]
for i in range(len(last_row)-1):
row.append(last_row[i]+last_row[i+1])
row+=[1]
result.append(row)
return row
But this results in the error
object of type 'int' has no len()
If i instead write
def pascal(n):
if n==1:
return [[1]]
else:
result=pascal(n-1)
row=[1]
last_row=result[-1]
for i in range(len(last_row)-1):
row.append(last_row[i]+last_row[i+1])
row+=[1]
result.append(row)
return result
And then call pascal(3)[-1], there is no problem. How can I fix this issue? Thanks.

You want pascal(n) to return the nth line of the Pascals triangle as a list, but you are returning [[1]] instead of [1] for pascal(1).
Also, the "last_row", i.e the previous row corresponding to pascal(n) would be pascal(n-1) and not pascal(n-1)[-1]. In your code, result[-1] is pascal(n-1)[-1] which the last element (int) of the (n-1)th row, hence the error.
This would be your function after making the above 2 changes.
def pascal(n):
if n == 0:
return [1]
else:
last_row = pascal(n-1)
row = [1]
for i in range(len(last_row)-1):
row.append(last_row[i]+last_row[i+1])
row += [1]
return row

Related

Write a program to determine if a given list possesses an additive sequence

I am an undergraduate student who love programming. I had met a problem today which confuses me a lot.
Write a program to determine if a given list possesses an additive
sequence. That is, a sequence of 3 consecutive elements where the
first two elements sum to the third. Return the sum value. Or return
None if there are no such sums.
Example 1:
Input: [0,1,2,3,5,8,13]
Output: 3, since 1+2 = 3. Note that 8 is also the sum of the two previous values, but it occurs after 3
Example 2:
Input: [1,2,4,5,6]
Output: None. Since no consecutive values sum to a third consecutive value.
My answer is:
def sequence_sum(my_list):
for x in range(0, len(my_list)):
if (my_list[x] + my_list[x+1]) != my_list[x+2]:
return None
else:
return my_list[x+2]
The test results read as:
Traceback (most recent call last):
File "/grade/run/test.py", line 30, in test_larger
self.assertEqual(sequence_sum(my_arr), 1)
AssertionError: None != 1
As well as:
Traceback (most recent call last):
File "/grade/run/test.py", line 35, in test_another
self.assertEqual(sequence_sum([0,3,4,5,9]), 9)
AssertionError: None != 9
for x in range(0, len(my_list)):
if (my_list[x] + my_list[x+1]) != my_list[x+2]:
return None
else:
return my_list[x+2]
It is a mistake to have both branches return because it means either way the function will return in the very first iteration of the loop. If you find a match it is correct to return straightaway. But when you don't find a match, you can't declare failure. There may be a match later. The return None needs to be delayed until the entire list has been searched.
for x in range(0, len(my_list)):
if my_list[x] + my_list[x+1] == my_list[x+2]:
return my_list[x+2]
return None
That'll fix the immediate problem, but run it and you will now encounter index out of range exceptions. I'll leave it to you to debug that problem.
Seems to me that you're only checking the first portion of the list. return will exit the function no matter where it is so after checking if 0 + 3 equals 4 it returns None. Therefore never getting to the end to check for 9.
To fix this move your return to the end of the function and chance the comparator to ==.
for loop:
if ([list[x]+list[x+1]) == list[x+2]:
return list[x+2]
return None
for x in range(0, len(my_list) - 2):
if my_list[x] + my_list[x + 1] == my_list[x + 2]:
return my_list[x + 2]
return None
You are checking for all the indexes (0, 1, 2, 3...) until the second one before the last as to not trigger an index out of boundary exception.
There, you check if any of the two consecutive ones are a sum of the next element in the list.
If there is such pair, you return it. If there is not (after going through the whole list), you return None.
You can use deque to save two last elements:
from collections import deque
def func(l: list):
seq = deque(maxlen=2)
for num, i in enumerate(l):
if num > 1 and sum(seq) == i:
return i
else:
seq.append(i)
print(func([0, 1, 2, 3, 5, 8, 13]))
# 3
print(func([1,2,4,5,6]))
# None
Yet another way:
found_sums = [x for i, x in enumerate(data[2:])
if data[i] + data[i+1] == x]
first_value = next(iter(found_sums), None)
found_sums is a list comprehension that returns the values which are equal to the sum of the two preceding ones. first_value returns the first of these values or alternatively None, if the list is empty.
Test:
for data in ([0,1,2,3,5,8,13], [1,2,4,5,6]):
found_sums = [x for i, x in enumerate(data[2:]) if data[i] + data[i + 1] == x]
first_value = next(iter(found_sums), None)
print('Result for {}:\t{}'.format(data, first_value))
This returns:
Result for [0, 1, 2, 3, 5, 8, 13]: 3
Result for [1, 2, 4, 5, 6]: None

How to fix 'IndexError: list index out of range' error

I am a beginner and took python and introductory algorithms and was trying to implement what I was learned. I was trying the following code but I keep getting an error:
IndexError: list index out of range
It fails at partition function, specifically at
array[0],array[pivot]=array[pivot],array[0]
line of code. I couldn't be able to fix it. Any help is appreciated.
from math import floor
def mergeSort(a): # mergesort function
if len(a)<2: # if length of a < 2, return a
return a
mid=int(len(a)/2) # mid point
x=mergeSort(a[:mid]) # recursively call mergesort for 0 to mid
y=mergeSort(a[mid:]) # recursively call mergesort from mid to end
result=[] # empty list
i=j=0 # initialize i and j
while j<len(x) and i<len(y):
if x[j]<y[i]: # if x[j] < y[i], then append result for x[j]
result.append(x[j])
j+=1 # increment j by 1
else:
result.append(y[i]) # append result for y[i]
i+=1 # increment i by 1
result+=x[j:] # add x[j:] --> result
result+=y[i:] # add y[i:] --> result
return result # return the result
def findMedian(a): # find the median
return mergeSort(a)[floor(len(a)/2)] # call mergesort
def choosePivot(a): # choose pivot
medians=[] # empty list
j=0 # initialize j
if len(a)==1: # if the len = 1, print the element
print (a[0])
return a[0]
if 5<len(a):
medians.append(findMedian(a[0:5])) # call findMedian for 0 to 5
else:
medians.append(findMedian(a)) # call findMedian for a
for i in range(1,floor(len(a)/5)): # divide the input array into 5 groups
if i*5<len(a):
medians.append(findMedian(a[j*5:i*5])) # call findMedian
else:
medians.append(findMedian(a[j*5:len(a)]))
return choosePivot(medians) # return choosePivot medians
def partition(array,pivot): # partition
array[0],array[pivot]=array[pivot],array[0] #swap
j=1 # intiatalize
for i in range(1,len(array)):
if array[i]<array[0]:
array[i],array[j-1]=array[j-1],array[i] #Swap the number less than the pivot
j+=1
array[1],array[j]=array[j],array[1] #swap the pivot to its rightful place
return j-1,array #return index of pivot and the partitioned array
def Selection(array,k): # selection function
p=choosePivot(array)
if k>len(array): # if k > length of array, then return -1
print ("Out of array index")
return -1
if len(array)>1: # if len(array) >1, then
x,b=partition(array,p) # call partition func
if x>k:
c = Selection(b[:x],k) # search the left half for the statistic
return c # return c
elif x<k:
d= Selection(b[x+1:],k-x-1) # search the right half for the statistic
return d # return d
else:
return array[k] # return the element if statistic is found
else:
return array[0] #Only one element. Only solution, return as it is.
print (Selection([5,1,48,6,2,4,8,7,5,63,2,1,4,8,99],13))
How to fix "index out of range" errors? Debugging. Great read: How to debug small programs (#1). Use print statements or better a debugger to stop at certain positions in your code and inspect whats going wrong. I use Visual Studio for that.
The red dot is a breakpoint - whenever the code hits the red dot it stops execution and I can inspect things to my hearts content. I can then advance line-wise. The yellow arrow shows in which line I am.
VS can pin variables as overlay to your sourcecode - see the small pieces to the right of the image.
List of debugging tools: https://wiki.python.org/moin/PythonDebuggingTools
When putting your program through VS the 3rd time it hits def partition(array,pivot): it is out of bounds:
Reason being that your pivot contains the value not the index that you need to swap it.
Even if you fix it to:
def partition(array,pivot): # partition
idx = array.index(pivot) # get the index of the value here
array[0],array[idx]=array[idx],array[0] #swap
j=1 # intiatalize
for i in range(1,len(array)):
if array[i]<array[0]:
array[i],array[j-1]=array[j-1],array[i] #Swap the number less than the pivot
j+=1
array[1],array[j]=array[j],array[1] #swap the pivot to its rightful place
return j-1,array #return index of pivot and the partitioned array
You run into another error when swapping array[1],array[j]=array[j],array[1] due to j being too large:
You need to fix your algorithms.
HTH

python for and while loop for tuples

I'm a beginner in python and was wondering why this function doesn't work. It is syntactically correct.
This function is supposed to collect every odd tuple item and I used a for loop as follows:
def oddTuples(aTup):
result = ()
for i in aTup:
if i % 2 == 0:
result += (aTup[i],)
return result
This is the 'correct' answer using while loop.
def oddTuples(aTup):
# a placeholder to gather our response
rTup = ()
index = 0
# Idea: Iterate over the elements in aTup, counting by 2
# (every other element) and adding that element to
# the result
while index < len(aTup):
rTup += (aTup[index],)
index += 2
return rTup
If anybody can help me, it would be much appreciated!
UPDATE
Okay, I got the problem, by 'i' I was merely collecting the real value within that tuple. I've fixed that, but this code is catching only some of the odd-idexed items, not all of them....
def oddTuples(aTup):
result = ()
for i in aTup:
index = aTup.index(i)
if index % 2 == 0:
result += (aTup[index],)
return result
Your for loop is iterating over the values in aTup, not the index of the values.
It appears your want your code to iterate over the index of the values or through a range of numbers starting with 0 and ending with the length of the tuple minus one and then use that number as the index to pull the value out of the tuple.
I didn't catch it on one go since it was syntactically correct too, but the error you are having is due to you iterating over the objects of the tuple (aTup) and not the indices. See here:
for i in aTup: # <-- For each *object* in the tuple and NOT indices
if i % 2 == 0:
result += (aTup[i],)
To fix the problem, use range() and len() over the aTup so that it iterates over the indices of the tuple instead, and change the if statement accordingly:
for i in range(len(aTup)):
if aTup[i] % 2 == 0:
result += (aTup[i],)
An alternative solution is to keep your object iterations but append the object directly to the result tuple instead of indexing:
for i in aTup:
if i % 2 == 0:
result += (i,)
Hope ths helped!
The reason is you are not using index..In below code i is not an index but the element in tuple but you are calling aTup[i] assuming i is an index which is not.
The below code will work fine - No need of doing aTup[i] or range.
def oddTuples(aTup):
result = ()
for i in aTup:
if i % 2 == 0:
result += (i,)
return result
Try replacing
def oddTuples(aTup):
result = ()
for i in aTup:
index = aTup.index(i)
if index % 2 == 0:
result += (aTup[index],)
return result
With
def oddTuples(aTup):
result = ()
for i in aTup:
index = aTup.index(i)
result += (aTup[index],)
return result
To fix you issue of it only doing the even numbered ones.
In simple words , if your tuple is
tup = (1, 2, 3, 4, 5 , 1000);
When your code is checking if each item is % 2 == 0 or not which is not what you want, from your description , you want only the items with odd index
So if you try the tuple above , you will get the following error:
IndexError: tuple index out of range , because for the 1000 it satisfy your condition and will do what is said in the if , trying to add the aTup(1000) (element of index 1000 in your input tuple) which doesn't exist as the tuple is only of 6 elements to your resultTuple
For this for loop to work , you can use the following method
def oddTuples(aTup):
result = ()
for i in aTup:
index = tup.index(i) # getting the index of each element
if index % 2 == 0:
result += (aTup[index],)
print(aTup[index])
return result
# Testing the function with a tuple
if __name__ == "__main__":
tup = (1, 2, 3, 7, 5, 1000, 1022)
tup_res = oddTuples(tup)
print(tup_res)
The result of this will be
1
3
5
1022
(1, 3, 5, 1022)
Process finished with exit code 0

python recursive pascal triangle

After completing an assignment to create pascal's triangle using an iterative function, I have attempted to recreate it using a recursive function. I have gotten to the point where I can get it to produce the individual row corresponding to the number passed in as an argument. But several attempts to have it produce the entire triangle up to and including that row have failed. I even tried writing a separate function which iterates over the range of the input number and calls the recursive function with the iterated digit while appending the individual lines to list before returning that list. The desired output should be a list of lists where each internal list contains one row of the triangle. Like so:
[[1], [1, 1], [1, 2, 1]...]
Instead it returns a jumbled mess of a nested list completely filled with 1's.
Here is the recursive function in question, without the second function to append the rows (I really wanted 1 all inclusive function anyway):
def triangle(n):
if n == 0:
return []
elif n == 1:
return [1]
else:
new_row = [1]
last_row = triangle(n-1)
for i in range(len(last_row)-1):
new_row.append(last_row[i] + last_row[i+1])
new_row += [1]
return new_row
To be clear, I have already completed the assigned task, this is just to provide a deeper understanding of recursion...
Iterative solution:
def triangle(n):
result = []
for row in range(n):
newrow = [1]
for col in range(1, row+1):
newcell = newrow[col-1] * float(row+1-col)/col
newrow.append(int(newcell))
result.append(newrow)
return result
You just need to pass a list of lists through the recursion, and pick off the last element of the list (i.e. the last row of the triangle) to build your new row. Like so:
def triangle(n):
if n == 0:
return []
elif n == 1:
return [[1]]
else:
new_row = [1]
result = triangle(n-1)
last_row = result[-1]
for i in range(len(last_row)-1):
new_row.append(last_row[i] + last_row[i+1])
new_row += [1]
result.append(new_row)
return result
An alternative to happydave's solution, using tail recursion:
def triangle(n, lol=None):
if lol is None: lol = [[1]]
if n == 1:
return lol
else:
prev_row = lol[-1]
new_row = [1] + [sum(i) for i in zip(prev_row, prev_row[1:])] + [1]
return triangle(n - 1, lol + [new_row])
I think its shod be helpful, this code draw triangle and do it recursively:
def traingle(n):
if n == 1:
print(1)
return [1]
else:
answer = [1]
print_able = '1 '
previos = traingle(n-1)
for index in range(len(previos)-1):
eleman = previos[index]+previos[index+1]
answer.append(eleman)
print_able += str(eleman)+' '
answer.append(1)
print_able += '1'
print(print_able)
return answer
end = int(input())
traingle(end)
Yes, as Karl Knechtel also showed, recursive Pascal Triangle can go this way :
P=lambda h:(lambda x:x+[[x+y for x,y in zip(x[-1]+[0],[0]+x[-1])]])(P(h-1))if h>1 else[[1]]
print(P(10))

counting odd numbers in a list python

This is a part of my homework assignment and im close to the final answer but not quite yet. I need to write a function that counts odd numbers in a list.
Create a recursive function count_odd(l) which takes as its only argument a list of integers. The function will return a count of the number of list elements that are odd, i.e., not evenly divisible by 2.\
>>> print count_odd([])
0
>>> print count_odd([1, 3, 5])
3
>>> print count_odd([2, 4, 6])
0
>>> print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
8
Here is what i have so far:
#- recursive function count_odd -#
def count_odd(l):
"""returns a count of the odd integers in l.
PRE: l is a list of integers.
POST: l is unchanged."""
count_odd=0
while count_odd<len(l):
if l[count_odd]%2==0:
count_odd=count_odd
else:
l[count_odd]%2!=0
count_odd=count_odd+1
return count_odd
#- test harness
print count_odd([])
print count_odd([1, 3, 5])
print count_odd([2, 4, 6])
print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
Can u help explain what im missing. The first two test harness works fine but i cant get the final two. Thanks!
Since this is homework, consider this pseudo-code that just counts a list:
function count (LIST)
if LIST has more items
// recursive case.
// Add one for the current item we are counting,
// and call count() again to process the *remaining* items.
remaining = everything in LIST except the first item
return 1 + count(remaining)
else
// base case -- what "ends" the recursion
// If an item is removed each time, the list will eventually be empty.
return 0
This is very similar to what the homework is asking for, but it needs to be translate to Python and you must work out the correct recursive case logic.
Happy coding.
def count_odd(L):
return (L[0]%2) + count_odd(L[1:]) if L else 0
Are slices ok? Doesn't feel recursive to me, but I guess the whole thing is kind of against usual idioms (i.e. - recursion of this sort in Python):
def countOdd(l):
if l == list(): return 0 # base case, empty list means we're done
return l[0] % 2 + countOdd(l[1:]) # add 1 (or don't) depending on odd/even of element 0. recurse on the rest
x%2 is 1 for odds, 0 for evens. If you are uncomfortable with it or just don't understand it, use the following in place of the last line above:
thisElement = l[0]
restOfList = l[1:]
if thisElement % 2 == 0: currentElementOdd = 0
else: currentElementOdd = 1
return currentElementOdd + countOdd(restOfList)
PS - this is pretty recursive, see what your teacher says if you turn this in =P
>>> def countOdd(l):
... return fold(lambda x,y: x+(y&1),l,0)
...
>>> def fold(f,l,a):
... if l == list(): return a
... return fold(f,l[1:],f(a,l[0]))
All of the prior answers are subdividing the problem into subproblems of size 1 and size n-1. Several people noted that the recursive stack might easily blow out. This solution should keep the recursive stack size at O(log n):
def count_odd(series):
l = len(series) >> 1
if l < 1:
return series[0] & 1 if series else 0
else:
return count_odd(series[:l]) + count_odd(series[l:])
The goal of recursion is to divide the problem into smaller pieces, and apply the solution to the smaller pieces. In this case, we can check if the first number of the list (l[0]) is odd, then call the function again (this is the "recursion") with the rest of the list (l[1:]), adding our current result to the result of the recursion.
def count_odd(series):
if not series:
return 0
else:
left, right = series[0], series[1:]
return count_odd(right) + (1 if (left & 1) else 0)
Tail recursion
def count_odd(integers):
def iter_(lst, count):
return iter_(rest(lst), count + is_odd(first(lst))) if lst else count
return iter_(integers, 0)
def is_odd(integer):
"""Whether the `integer` is odd."""
return integer % 2 != 0 # or `return integer & 1`
def first(lst):
"""Get the first element from the `lst` list.
Return `None` if there are no elements.
"""
return lst[0] if lst else None
def rest(lst):
"""Return `lst` list without the first element."""
return lst[1:]
There is no tail-call optimization in Python, so the above version is purely educational.
The call could be visualize as:
count_odd([1,2,3]) # returns
iter_([1,2,3], 0) # could be replaced by; depth=1
iter_([2,3], 0 + is_odd(1)) if [1,2,3] else 0 # `bool([1,2,3])` is True in Python
iter_([2,3], 0 + True) # `True == 1` in Python
iter_([2,3], 1) # depth=2
iter_([3], 1 + is_odd(2)) if [2,3] else 1
iter_([3], 1 + False) # `False == 0` in Python
iter_([3], 1) # depth=3
iter_([], 1 + is_odd(3)) if [3] else 1
iter_([], 2) # depth=4
iter_(rest([]), 2 + is_odd(first([])) if [] else 2 # bool([]) is False in Python
2 # the answer
Simple trampolining
To avoid 'max recursion depth exceeded' errors for large arrays all tail calls in recursive functions can be wrapped in lambda: expressions; and special trampoline() function can be used to unwrap such expressions. It effectively converts recursion into iterating over a simple loop:
import functools
def trampoline(function):
"""Resolve delayed calls."""
#functools.wraps(function)
def wrapper(*args):
f = function(*args)
while callable(f):
f = f()
return f
return wrapper
def iter_(lst, count):
#NOTE: added `lambda:` before the tail call
return (lambda:iter_(rest(lst), count+is_odd(first(lst)))) if lst else count
#trampoline
def count_odd(integers):
return iter_(integers, 0)
Example:
count_odd([1,2,3])
iter_([1,2,3], 0) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([2,3], 0+is_odd(1)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([3], 1+is_odd(2)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([], 1+is_odd(3))
2 # callable(2) is False
I would write it like this:
def countOddNumbers(numbers):
sum = 0
for num in numbers:
if num%2!=0:
sum += numbers.count(num)
return sum
not sure if i got your question , but as above something similar:
def countOddNumbers(numbers):
count=0
for i in numbers:
if i%2!=0:
count+=1
return count
Generator can give quick result in one line code:
sum((x%2 for x in nums))

Categories

Resources