0

Write a recursive Python function called odd_factorial(x) that for input x (x >= 5) calculates 3 × 5 × 7 × . . . × x, if x is odd; or 3 × 5 × . . . × (x − 1) if x 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)
4
  • 5
    Personally I'd keep it simple by having two functions. The first is the non-recursive entry point that both converts evens to x-1 and checks that the input is >=5. It then calls the second, which is the recursive function, and is a simpler and cleaner version of the function you already have. Commented Feb 15, 2015 at 11:22
  • 1
    are you sure about the condition x>=5 ? Commented Feb 15, 2015 at 11:22
  • What should the function return if x<5? What is the exit condition? Commented Feb 15, 2015 at 11:28
  • Remember to accept the most helpful answer to you! Commented Feb 16, 2015 at 15:39

6 Answers 6

1

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)
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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!

Comments

0

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

Comments

0

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")

1 Comment

this doesn't work! The initial condition prevents the function from continuing!
0

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))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.