Fonction factorielle Ruby
17 réponses
Il n'y a pas de fonction factorielle dans la bibliothèque standard.
Ce n'est pas dans la bibliothèque standard mais vous pouvez étendre la classe Integer.
class Integer
def factorial_recursive
self <= 1 ? 1 : self * (self - 1).factorial
end
def factorial_iterative
f = 1; for i in 1..self; f *= i; end; f
end
alias :factorial :factorial_iterative
end
N.B. la factorielle itérative est un meilleur choix pour des raisons évidentes de performance.
Sans vergogne bercé de http://rosettacode.org/wiki/Factorial#Ruby , Mon préféré est
class Integer
def fact
(1..self).reduce(:*) || 1
end
end
>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Cette implémentation est également la plus rapide parmi les variantes listées dans le code Rosetta.
Mettre à jour
Ajouté || 1
pour gérer le cas zéro.
Vous pouvez également utiliser Math.gamma
fonction qui se résume à de la factorielle pour les paramètres entiers.
En mathématiques, factorial of n
est juste le gamma function of n+1
(voir: http://en.wikipedia.org/wiki/Gamma_function)
Ruby a Math.gamma()
Il suffit donc d'utiliser Math.gamma(n+1)
et de le renvoyer à un entier si désiré.
class Integer
def !
(1..self).inject(:*)
end
end
Exemples
!3 # => 6
!4 # => 24
Je viens d'écrire le mien:
def fact(n)
if n<= 1
1
else
n * fact( n - 1 )
end
end
En outre, vous pouvez définir une factorielle en baisse:
def fall_fact(n,k)
if k <= 0
1
else
n*fall_fact(n - 1, k - 1)
end
end
L'utilisation de Math.gamma.floor
est un moyen facile de produire une approximation, puis de l'arrondir au résultat entier correct. Devrait fonctionner pour tous les entiers, inclure une vérification d'entrée si nécessaire.
Appelez simplement cette fonction
def factorial(n=0)
(1..n).inject(:*)
end
Exemples
factorial(3)
factorial(11)
Juste une autre façon de le faire, même si ce n'est vraiment pas nécessaire.
class Factorial
attr_reader :num
def initialize(num)
@num = num
end
def find_factorial
(1..num).inject(:*) || 1
end
end
number = Factorial.new(8).find_factorial
puts number
Vous trouverez probablement une demande de fonctionnalité Ruby utile. Il contient un patch non trivial qui inclut un script Demo Bash. La différence de vitesse entre une boucle naïve et la solution présentée dans le lot peut être littéralement 100x (cent fois). Écrit tout en pur Rubis.
class Integer
def factorial
return self < 0 ? false : self==0 ? 1 : self.downto(1).inject(:*)
#Not sure what other libraries say, but my understanding is that factorial of
#anything less than 0 does not exist.
end
end
Et encore une autre façon (=
def factorial(number)
number = number.to_i
number_range = (number).downto(1).to_a
factorial = number_range.inject(:*)
puts "The factorial of #{number} is #{factorial}"
end
factorial(#number)
Voici ma version semble être claire pour moi même si elle n'est pas aussi propre.
def factorial(num)
step = 0
(num - 1).times do (step += 1 ;num *= step) end
return num
end
C'était ma ligne de test irb qui montrait chaque étape.
num = 8;step = 0;(num - 1).times do (step += 1 ;num *= step; puts num) end;num
Juste une autre façon de faire:
# fact(n) => Computes the Factorial of "n" = n!
def fact(n) (1..n).inject(1) {|r,i| r*i }end
fact(6) => 720