2013-11-19 1 views
2
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 

Когда я вводим нечетное число, например: факт 5 даст 15, так как это должно 1 * 3 * 5 = 15. Однако я понял, что если я делаю факт 7 или любое другое нечетное число, оно только умножает первые два нечетных числа. Как заставить функцию умножить все нечетные числа, а не только первые 2. Например. факт 7 = 35 (т. е. 3 * 5). Также обратите внимание, что если введено четное число, он будет обрабатывать факториал всех нечетных чисел до и не включать четное число.Haskell - Попытка создать функцию для поиска факториала нечетных чисел

ответ

3

Ты проблема заключается в том, что ваш случай для четного числа является n-1, что означает, что, когда вы получите нечетное число, вы на самом деле просто делаете

n * (n - 1 - 1) 

Когда то, что вы хотите

п * п-2 * п-4 ...

Так что попробуйте это вместо

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) 

Я также взял на себя смелость устранить некоторую избыточную логику. Здесь мы уменьшаем на два, если это нечетно, поэтому 5 -> 3. И в четном случае мы уменьшаем на единицу, чтобы заканчиваться на нечетном числе и что рекурсия на это.

+0

Я думаю, что для нечетных чисел больше, чем один он на самом деле 'факта (п-1) * п, где факт х = х-1 ', который является' факта (п-1) * n где fact (n-1) = (n-1) -1', который является '((n-1) -1) * n', который является' n * (n-2) '. – Cirdec

+0

Все числа, которые я пробовал, равны 0, имеет ли он что-то общее с n-2? В моем коде, когда я пытался n-2, у меня не было n <0 = 0, и ответ попал в негативы. –

+0

@Cirdec Совершенно верно, обновлено – jozefg

4

Это напоминает мне о знаменитом Evolution of a Haskell Programmer. Перефразируя ответ на штатных профессорах:

factorialOfOdds :: Integer -> Integer 
factorialOfOdds n = product [1,3..n]