Pergunta

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.

Foi útil?

Solução 2

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.

Outras dicas

This reminds me of the famous Evolution of a Haskell Programmer. Paraphrasing the tenured professor's answer:

factorialOfOdds :: Integer -> Integer
factorialOfOdds n = product [1,3..n]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top