Search code examples
functionhaskellrecursionfactorial

Haskell - Trying to create a function to find the factorial of odd numbers


fact :: Int -> Int 
fact n
    |n < 0 = 0
    |n == 0 = 1
    |n > 0 && n `mod` 2 == 1 = fact (n-1) * n
    |n > 0 && n `mod` 2 == 0 = n-1

When I enter an odd number for example: fact 5 will give 15, as it should 1 * 3 * 5 = 15. However I realized that if I do fact 7 or any other odd number, it only multiplies the first two odd numbers. How do I get the function to multiply all the odd numbers and not just the first 2. Eg. fact 7 = 35 (ie. 3 * 5). Also note, that if an even number is entered, it will work out the factorial of all the odd numbers up until and not including the even number.


Solution

  • You're problem is that your case for an even number is n-1, which means that when you get to an odd number you're really just doing

    n * (n - 1 - 1)
    

    When what you want is

    n * n-2 * n-4 ...

    So try this instead

    fact :: Integer -> Integer -- Overflows 
    fact n
        |n < 0 = 0
        |n == 0 || n == 1 = 1
        |n `mod` 2 == 1 = fact (n-2) * n
        |n `mod` 2 == 0 = fact (n-1)
    

    I also took the liberty of removing some redundant logic. Here we decrement by two if it's odd, so 5 -> 3. And in the even case we decrement by one to end up on an odd number and that recurse on that.