I need a function that takes n and returns 2n - 1 . It sounds simple enough, but the function has to be recursive. So far I have just 2n:
def required_steps(n):
if n == 0:
return 1
return 2 * req_steps(n-1)
The exercise states: "You can assume that the parameter n is always a positive integer and greater than 0"
2**n -1 is also 1+2+4+...+2n-1 which can made into a single recursive function (without the second one to subtract 1 from the power of 2).
Hint: 1+2*(1+2*(...))
Solution below, don't look if you want to try the hint first.
This works if n is guaranteed to be greater than zero (as was actually promised in the problem statement):
def required_steps(n):
if n == 1: # changed because we need one less going down
return 1
return 1 + 2 * required_steps(n-1)
A more robust version would handle zero and negative values too:
def required_steps(n):
if n < 0:
raise ValueError("n must be non-negative")
if n == 0:
return 0
return 1 + 2 * required_steps(n-1)
(Adding a check for non-integers is left as an exercise.)
To solve a problem with a recursive approach you would have to find out how you can define the function with a given input in terms of the same function with a different input. In this case, since f(n) = 2 * f(n - 1) + 1, you can do:
def required_steps(n):
return n and 2 * required_steps(n - 1) + 1
so that:
for i in range(5):
print(required_steps(i))
outputs:
0
1
3
7
15
You can extract the really recursive part to another function
def f(n):
return required_steps(n) - 1
Or you can set a flag and define just when to subtract
def required_steps(n, sub=True):
if n == 0: return 1
return 2 * required_steps(n-1, False) - sub
>>> print(required_steps(10))
1023
Using an additional parameter for the result, r -
def required_steps (n = 0, r = 1):
if n == 0:
return r - 1
else:
return required_steps(n - 1, r * 2)
for x in range(6):
print(f"f({x}) = {required_steps(x)}")
# f(0) = 0
# f(1) = 1
# f(2) = 3
# f(3) = 7
# f(4) = 15
# f(5) = 31
You can also write it using bitwise left shift, << -
def required_steps (n = 0, r = 1):
if n == 0:
return r - 1
else:
return required_steps(n - 1, r << 1)
The output is the same
Have a placeholder to remember original value of n and then for the very first step i.e. n == N, return 2^n-1
n = 10
# constant to hold initial value of n
N = n
def required_steps(n, N):
if n == 0:
return 1
elif n == N:
return 2 * required_steps(n-1, N) - 1
return 2 * required_steps(n-1, N)
required_steps(n, N)
One way to get the offset of "-1" is to apply it in the return from the first function call using an argument with a default value, then explicitly set the offset argument to zero during the recursive calls.
def required_steps(n, offset = -1):
if n == 0:
return 1
return offset + 2 * required_steps(n-1,0)
On top of all the awesome answers given earlier, below will show its implementation with inner functions.
def outer(n):
k=n
def p(n):
if n==1:
return 2
if n==k:
return 2*p(n-1)-1
return 2*p(n-1)
return p(n)
n=5
print(outer(n))
Basically, it is assigning a global value of n to k and recursing through it with appropriate comparisons.
Related
I've got a question- how do I write a function sum_even_factorials that finds the sum of the factorials of the even numbers that are less than or equal to n.
Eg:
sum_even_factorials(1)=
1
sum_even_factorials (3)=
3
sum_even_factorials (6)=
747
This is my current code:
Is there a logical error in the current code?
Is there a logical error in the current code?
To begin with, function sum_even_factorial doesn't return a value in every execution flow:
if cond1:
return val1
elif cond2:
return val2
else: # this part is missing in your code
return val3
In addition, note that when you call this function, you are not doing anything with the value that it returns:
sum_even_factorial(6)
Finally, although parts of your code are not visible in your question, I tend to guess that you cannot recursively compute the factorials of even numbers the way you did it, because the factorial of an even number n depends on the factorial of the odd number n - 1.
I think the code needs a loop. I'd write it like so:
def factorial(n):
if n == 0 or n == 1:
return 1;
else:
return n * factorial(n-1)
def sum_even_factorial(n):
current_sum = 0
while n >= 0:
if n % 2 == 0:
current_sum += factorial(n)
n -= 1
return current_sum
print(sum_even_factorial(6))
If you return tuples from the function, you can do it with one single function. See the comments in the code on how it works ...
def factorial_with_sum(n):
if n < 2:
return 1, 0 # first item of the tuple is the factorial, second item is the sum
else:
f, s = factorial_with_sum(n - 1) # calc factorial and sum for n - 1
f = f * n # factorial = n * factorial (n - 1)
if n % 2 == 0:
s = s + f # if n is even, add the current factorial to the sum
return f, s
fact, sum = factorial_with_sum(6)
print(fact)
print(sum)
You can also do it iteratively with a simple for loop as follows
def factorial_with_sum_iterative(n):
s = 0 # initialize sum
f = 1 # and factorial
for i in range(2, n + 1): # iterate from 2 to n
f = f * i # calculate factorial for current i
if i % 2 == 0:
s = s + f # if current i is even, add it to sum
return f, s
def bounce(n):
if n < 1:
return 0 #if I change this value to 1 n gets printed out correctly, why?
else:
return n * bounce(n - 1)
print(bounce(5))
Your base case is return 0. After the line return n * bounce(n - 1) where n is 1, bounce(0) will be executed, returning 0 and multiplying all your previous results by 0.
Following the calls, we see:
5>=1, so return 5*bounce(4)
4>=1, so return 5*4*bounce(3)
3>=1, so return 5*4*3*bounce(2)
2>=1, so return 5*4*3*2*bounce(1)
1>=1, so return 5*4*3*2*1*bounce(0)
0<1, so return 5*4*3*2*1*0
meaning everything gets zeroed out at the end.
You want the base case to be 1 for that reason.
You sould add an check that returns the value for 0.
Otherwise you recursion multiplys with 0 at the final call of the recursiv function.
def bounce(n):
if n < 1:
return 0
elif n == 1:
return 1
else:
return n * bounce(n - 1)
This recursion is returning 0 because when n = 1, your compiler goes inside the else block and calls return 1 * bounce(0), and this time the compiler returns 0 because the if-condition is satisfied here. If you want your output to be 120 (in this case), you can change your code like this:
def bounce(n):
if n < 1:
return 0
else :
if n == 1:
return n ;
return n * bounce(n - 1)
print(bounce(5))
Yes, you have a loop that will continually repeat until you get to the point that n = 0, and you are printing a product where at least one value has "n * 0" in it.
A function that calculates (n-1)! , but with steps.
def function1(n, step):
result = 1
for i in range(1, n, step):
result *= i
return result
I'm not allowed to add any more parameters and I need to make it recursive.
I've tried this:
def function2(n, step):
if n < 0:
return 1
return n * function2(n-step, step)
But for let's say:
function2(6,3)
it wouldn't work, the first function will give me 1 * 4
and the second one would give me 6 * 3 * 1
I don't know how to make it work with the step argument.
Edit:
Some more samples:
First function
function1(13, 3) == 280
function1(11, 3) == 280
function1(6, 3) == 4
function1(11, 2) == 945
function1(8, 2) == 105
function1(4, 2) == 3
More sample:
function1(12, 3) == 280
function1(5, 2) == 3
function1(5, 3) == 4
Second function (same values):
function2(13, 3) == 3640
function2(11, 3) == 880
function2(6, 3) == 0
function2(11, 2) == 10395
function2(8, 2) == 0
function2(4, 2) == 0
Edit2: Some more clarifications: The function computes (n-1)!, but with steps. The step argument would just "step over" or "skip" some numbers (e.g.: function1(12, 3) should compute 1*4*7*10, like with the step argument from range(), cause it's used in the first function)
Thank you!
The obvious difference is that you are building range starting at 1 and counting up to n by step, and in the recursive example you are starting at n and counting down by step. This will result in different numbers being multiplied.
Because you are required not to use any additional function parameters, I would suggest an inner helper function, loop -
def fact (n, step):
def loop (m):
if m >= n:
return 1
else:
return m * loop(m + step)
return loop(1)
If you don't want to use a helper function like loop above, you are constrained to complex modulus arithmetic -
def fact (n, step):
if n % step != 1:
return fact(n + 1, step)
elif n < step:
return 1
else:
return (n - step) * fact(n - step, step)
No matter which way you shake it, the modulus operation for this problem is messy -
def fact (n, step):
q = (n - 1) % step
if q:
return fact(n + step - q, step)
elif n < step:
return 1
else:
return (n - step) * fact(n - step, step)
Once academic constraints like "do not use additional parameters" go away, you can multiply the ascending series in a more familiar way -
def fact (n, step, m = 1):
if m >= n:
return 1
else:
return m * fact(n, step, m + step)
All variations of fact above produce identical output -
print(fact(13, 3) == 280) # True
print(fact(11, 3) == 280) # True
print(fact(6, 3) == 4) # True
print(fact(11, 2) == 945) # True
print(fact(8, 2) == 105) # True
print(fact(4, 2) == 3) # True
print(fact(5, 2) == 3) # True
print(fact(5, 3) == 4) # True
Because the steps is calculated beginnig with 1 You have to normalize n to be a multiple of step plus 1 before you begin
And you can cheat the number of arguments by setting the steps negative on recursive calls.
def function2(n, step):
if n <= 1:
return 1
if step > 0:
n = n - 2
n = n - n % step + 1
step = -step
return n * function2(n + step, step)
I am trying to write a function that will return a list of the first n catalan numbers. This is what I have come up with so far.
def catalan_numbers(n):
if n == 0:
return 1
else:
n -= 1
return int((((2*n+2) * (2*n+1))/((n+1)*(n+2))) * catalan_numbers(n))
So far this provide me with a correct solution for a single index. So if I were to call catalan_numbers(4), 14 would be returned which is correct but exactly what I am seeking. I tried to fix this issue doing the following:
def catalan_numbers(n):
catalan = [1]
for x in range(0, n):
catalan.append(int((((2*n+2) * (2*n+1))/((n+1)*(n+2))) * catalan_numbers(n))
return catalan
But this returns:
RuntimeError: maximum recursion depth exceeded in comparison
the error is because you don't have a base case also check the following code instead of returning a one number it returns a list and concatenate the current n catalan number with the list for n-1
def catalan_numbers(n):
if n == 0:
return [1]
else:
n -= 1
t = catalan_numbers(n)
return t + [int((((2*n+2) * (2*n+1))/((n+1)*(n+2))) * t[-1])]
I would suggest iteration over recursion:
def catalan_numbers(N):
C = [1]
for n in range(1, N):
C.append((4*n - 2) * C[-1] // (n + 1))
return C
EDIT: I know I can import factorials but I'm doing this as an exercise
Trying to get the factor of a given number with a function in Python.
For example:
factorial(4) = 4 * 3 * 2 * 1 = 24
def factorial(x):
n = x
while n >= 0:
x = n * (n - 1)
n -= 1
return x
try like this: to make your code work
def factorial(x):
n = 1 # this will store the factorial value
while x > 0:
n = n*x
x -= 1
return n
you got many advice on comments follow it
A good way of approaching this would be using recursion where a function calls itself. See Function for Factorial in Python
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
But in your case your return statement actually breaks out of the while loop. So if you pass in 5 you get 20 back which is obviously not 5! (5 factorial).
Instead, try this:
def factorial(x):
n = 1
while x > 1:
n *= x
x -= 1
return n
print (factorial(5))
But do have a go at the recursive approach.
If you really want to cheat try:
import math
math.factorial(n)
I present an even shorter code for recursive factorial calculation. Not sure if it is faster or slower than other approaches:
def fac(n):
return 1 if n==1 else n*fac(n-1)
fac(10)
3628800
def factorial(n):
total = 1
for num in range(2,n+1):
total *= num
return total
input:
n = 10
print(str(n) + "! = ", end = '')
def factorial(n):
'''
print factorial number in human way
'''
if n < 0:
return 'factorial() not defined for negative values'
if n == 0:
return 1
if n == 1:
print('', n, ' =', end = ' ')
return 1
else:
print('', n, '*', end = '')
return n * factorial(n - 1)
print(factorial(n))
output:
10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 3628800