Reputation: 21
Write a recursive Python function called
odd_factorial(x)
that for inputx
(x >= 5
) calculates3 × 5 × 7 × . . . × x
, ifx
is odd; or3 × 5 × . . . × (x − 1)
ifx
is even.
I have the recursion but I am not quite sure how to ensure x >= 5
for the first loop:
def odd_factorial(x):
if x%2 == 1:
if x == 3:
return 3
else:
return x*odd_factorial(x-2)
else:
x -= 1
if x == 3:
return 3
else:
return x*odd_factorial(x-2)
Upvotes: 0
Views: 791
Reputation: 4093
Here is a very simple recursive factorial program using just the odd numbers
#Factorial using Recursion
n = int(input("Enter the n value for Factorial:"))
def factorial(n):
if n<=1:
return 1
else:
return n*factorial(n-2)
print(factorial(n))
Upvotes: 0
Reputation: 20339
Simply complicated :)
def odd_factorial(x, signal=None):
if x < 5 and signal==None:
return "number should be greater than 5"
else:
if x%2 == 1:
if x == 3:
return 3
else:
return x*odd_factorial(x-2, signal="r")
else:
x -= 1
if x == 3:
return 3
else:
return x*odd_factorial(x-2, signal="r")
Upvotes: 0
Reputation: 180391
add an extra check setting a flag so you catch values entered < 5 if it is the first call of the function, you can also remove the else from your code as you can only return any one line at a time:
def odd_factorial(x, flag=True):
if x < 5 and flag:
return "Only numbers >= 5"
if x % 2: # or if x & 1
return x * odd_factorial(x - 2, False) if x != 3 else 3
x -= 1
return x * odd_factorial(x - 2, False)
In [32]: odd_factorial(5)
Out[32]: 15
In [33]: odd_factorial(3)
Out[33]: 'Only numbers >= 5'
In [34]: odd_factorial(7)
Out[34]: 105
Upvotes: 0
Reputation: 720
Why not simply change the way it is calculated:
def odd_factorial(x):
if x%2 == 0:
x -= 1
if x == 5:
return 3*5
elif x < 5:
raise ValueError("Input should not be < 5")
else:
return x*odd_factorial(x-2)
This is good because you don't repeat yourself as you did before (with the even/odd check) and you still follow the specification!
Upvotes: 0
Reputation: 133899
This will be speedier and cleaner as it does not do conditioning in the actual recursion. It is still a function, albeit with another nested in.
def odd_factorial(x):
def do_fact(x):
if x == 3:
return 3
return x * do_fact(x - 2)
if x < 5:
raise ValueError("X must be at least 5")
if not x % 2:
x -= 1
return do_fact(x)
Running:
>>> odd_factorial(5)
15
>>> odd_factorial(6)
15
>>> odd_factorial(7)
105
>>> odd_factorial(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 9, in odd_factorial
raise ValueError("X must be at least 5")
ValueError: X must be at least 5
>>> odd_factorial(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 9, in odd_factorial
raise ValueError("X must be at least 5")
ValueError: X must be at least 5
Another way is to return 15
for odd_factorial(5)
and odd_factorial(6)
directly:
def odd_factorial(x):
if x < 5:
raise ValueError("x must be at least 5")
if x % 2 == 0:
x -= 1
if x == 5:
return 15
return x * odd_factorial(x - 2)
Upvotes: 1
Reputation: 6141
Use an inner function, saves you an extra parameter:
>>> def odd_factorial(input):
def odd_factorial_inner(x):
if x%2 == 1:
if x == 3:
return 3
else:
return x*odd_factorial_inner(x-2)
else:
x -= 1
if x == 3:
return 3
else:
return x*odd_factorial_inner(x-2)
if (input >= 5):
return odd_factorial_inner(input)
else:
print "input is smaller than 5"
>>> odd_factorial(9)
945
>>> odd_factorial(4)
Input is smaller than 5.
Upvotes: 0