how to compute a%b recursively? - recursion

I need to write a recursive function that returns the remainder of two numbers. Here's what I wrote:
def remainder(a,b):
if a==b:
return 0
else:
k=a-b
return a-b + remainder(b,a-k)
If we test remainder(5,3) the function will return 2 and it's correct but if we test remainder(15,3),
we'll get 12 and its false. I just don't know how to debug it.

You are missing a case: (when a < b)
def remainder(a,b):
if a<b: #trivial: remainder = a - b*0 = a
return a
else: #reduce the problem to a simple one
return remainder(a-b, b)
Test:
print remainder(15,3)
Output:
0
Here if you are lazy and don't want to write more than 2 lines:
def remainder(a,b):
return a if a < b else remainder(a-b, b)

It should be something like this :
def remainder(a,b):
if a<b:
return a
else:
return remainder(a-b,b)

You can do:
def remainder(a, b):
if a < b:
return a
return remainder(a - b, b)
Examples:
>>> remainder(15, 3)
0
>>> remainder(14, 3)
2
>>> remainder(13, 3)
1
If a < b then it means we're done: we know the result of the computation and we can return a. Otherwise we need to subtract b from a and we call remainder again recursively. This can then repeatedly continue until a is smaller than b. Once that happens the recursion stops (i.e., it won't call remainder again) but we're able to return the result.

Related

how to find how many times does something appears in a list recursively (python)

imagine if i had a list ([1,2,2,3,2]) and i want to find how many times does the number 2 appear in the list, how would i do it recursively, do i set my counter to 0 in my base case? How do i make the list count my desired item.
def rc_count(L, x):
if len(L)==0:
n=0
return n
else:
rc_count(L[1:], x)
if L[0]==x:
n+=1
return n
it says local variable n referenced before assignment so where should i put my counter
I do not really se the reason for this recursive function. However this is how you would do it:
def rc_count(l,x):
n = 0
if not l:
return n
else:
n = re(l[1:], x)
if l[0] == x:
n+=1
return n
Here rc_count([1,2,2,2,2,3,4,5],2) will return 4

How to optimize this recursion function?

This is really similar to Fibonacci Sequence problem. I understand the DP optimization with Fibonacci function using the for loop, but I'm having hard time to connect to this problem.
The recursion function I want to optimize is:
def cal(n):
if n <= 0:
return 1
else:
return cal(n-25)+cal(n-26)
Something like this may help:
(It's inspired by previous post)
from functools import cache
#cache
def cal(n):
if n <= 0:
return 1
else:
return cal(n-25) + cal(n-26)
print(cal(100))
The idea of a "for loop optimization" is that we calculate cal(0), cal(1), cal(2), ... consecutively. And when we want cal(n), we already have cal(n-25) and cal(n-26) stored in an array.
So, the following solution has linear complexity for non-negative n:
def cal(n):
mem = [1] # cal(0) is 1
for i in range(1, n + 1):
num = 1 if i - 25 < 0 else mem[i - 25]
num += 1 if i - 26 < 0 else mem[i - 26]
mem.append (num)
return mem[-1]
One can further optimize to make all the values cal(1), cal(2), ..., cal(n) globally available after calculating the last of them.

Python dictionary setdefault() method used as a return value of a recursive function

Say you want to get the nth Fibonacci Number. Then, one possibility is to use the recursive function
def Fib(n, d):
"""Assumes n is an int >= 0, d dictionary
Returns nth Fibonacci number"""
if n in d:
return d[n]
else:
d[n] = Fib(n-1, d) + Fib(n-2, d)
return d[n]
This works quite well. I tried to shorten this to
def Fib(n, d):
return d.setdefault(n, Fib(n-1, d) + Fib(n-2, d))
But when I can call it with
d={0:1, 1:1}
print(f(2, d))
, or even with f(1,d), it goes into infinite loop, and restarts the kernel. In fact, any function of this form, say
def f(n, d):
return d.setdefault(n, f(n-1,d))
has the same problem. When I tried to debug this, I saw that n keeps decreasing pass the value 1. I guess I don't understand the implementation of this method. I presumed that the setdefault method first checks whether the key is in the dictionary and returns the value, and if not, then assigns the default value to the key and returns the default value. What am I missing here?(I am using Python 3.9.1 with Spyder 4.2.0)
You still need a base case otherwise there's nothing to stop it from calculating, fib(-1), fib(-2), fib(-99), ...
def fib(n, d):
return n if n < 2 else d.setdefault(n, fib(n-1, d) + fib(n-2, d))
print(fib(10, {0:0, 1:1}))
55
The problem you are experiencing with setdefault is that python is an applicative order language. That means a functions arguments are evaluated before a the function is called. In the case of setdefault, we will evaluate fib(n-1,d) + fib(n-2,d) before we attempt to lookup n in d.
A better interface might be dict.setdefault(key, lambda: somevalue) where the lambda is executed only if the default needs to be set. We could write this as lazydefault below -
def lazydefault(d, key, lazyvalue):
if key not in d:
d[key] = lazyvalue()
return d[key]
def fib(n, d):
return lazydefault(d, n, lambda: fib(n-1, d) + fib(n-2, d))
print(fib(10, {0:0, 1:1}))
55

Reverse order recursion

I want to print out the elements in the list in reverse order recursively.
def f3(alist):
if alist == []:
print()
else:
print(alist[-1])
f3(alist[:-1])
I know it is working well, but I don't know the difference between
return f3(alist[:-1])
and
f3(alist[:-1])
Actually both are working well.
My inputs are like these.
f3([1,2,3])
f3([])
f3([3,2,1])
There is a difference between the two although it isn't noticeable in this program. Look at the following example where all I am doing is passing a value as an argument and incrementing it thereby making it return the value once it hits 10 or greater:
from sys import exit
a = 0
def func(a):
a += 1
if a >= 10:
return a
exit(1)
else:
# Modifications are made to the following line
return func(a)
g = func(3)
print(g)
Here the output is 10
Now if I re-write the code the second way without the "return" keyword like this :
from sys import exit
a = 0
def func(a):
a += 1
if a >= 10:
return a
exit(1)
else:
# Modifications are made to the following line
func(a)
g = func(3)
print(g)
The output is "None".
This is because we are not returning any value to handle.
In short, return is like internal communication within the function that can be possibly handled versus just running the function again.

Recursive method function that counts binary 1s of an integer

I want to write a recursive method function that takes a nonnegative integer n as input and returns the number of 1s in the binary representation on n. I am instructed to use the fact that this is equal to the number of 1s in the representation of n//2 (integer division), plus 1 if n is odd.
Usage:
>>> ones(0)
0
>>> ones(1)
1
>>> ones(14)
3
ok so this is the code I got so far, it still doesn't work though. it gives me 0 no matter what I input as n.
def numOnes(n):
# base case
if n==0:
print (0)
elif n ==1:
print (1)
# recursive case
else:
return numOnes(n//2)+numOnes(n%2)
Thank you
These elements you need to do it yourself:
if integer & 1 == 1: # & is the binary and. & 1 will give the lowest bit
# there is a 1 in the end
integer = integer // 2 # loose one bit in the end
# or
integer = integer >> 1 # loose one bit in the end
Tell me if you need more input.
Your code works for me:
>>> def numOnes(n):
# base case
if n==0:
return (0)
elif n == 1:
return (1)
# recursive case
else:
return numOnes(n//2)+numOnes(n%2)
>>> numOnes(0b1100011)
4
You use print instead of return for the two base cases. Fix that and it'll work:
In [2]: numOnes(15842)
Out[2]: 9
In [3]: bin(15842).count('1')
Out[3]: 9

Resources