web-dev-qa-db-fra.com

Ruby fonction factorielle

Je deviens fou: Où est la fonction Ruby pour factorielle? Non, je n'ai pas besoin d'implémentations de tutoriel, je veux juste la fonction de la bibliothèque. Ce n'est pas en Maths!

Je commence à douter, est-ce une fonction de bibliothèque standard?

85
rutger

Il n'y a pas de fonction factorielle dans la bibliothèque standard.

133
sepp2k

Comme c'est mieux

(1..n).inject(:*) || 1
101
Alexander Revutsky

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 performances.

77

Crépité sans vergogne 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 s'avère également être la plus rapide parmi les variantes répertoriées dans le code Rosetta.

mise à jour # 1

Ajoutée || 1 pour gérer le cas zéro.

mise à jour # 2

Merci et appréciation à Mark Thomas , voici une version un peu plus efficace, élégante et obscure:

class Integer
  def fact
    (2..self).reduce(1,:*)
  end
end
22
fearless_fool

Vous pouvez également utiliser Math.gamma fonction qui se résume à factorielle pour les paramètres entiers.

class Integer
  def !
    (1..self).inject(:*)
  end
end

exemples

!3  # => 6
!4  # => 24
12
jasonleonhard

En mathématiques, factorial of n N'est que le gamma function of n+1
(voir: http://en.wikipedia.org/wiki/Gamma_function )

Ruby a Math.gamma() alors utilisez simplement Math.gamma(n+1) et convertissez-le en entier si vous le souhaitez.

12
Albert Renshaw

Je ferais

(1..n).inject(1, :*)
8
Santhosh

Je viens d'écrire le mien:

def fact(n)
  if n<= 1
    1
  else
    n * fact( n - 1 )
  end
end

Vous pouvez également définir une factorielle descendante:

def fall_fact(n,k)
  if k <= 0
    1
  else
    n*fall_fact(n - 1, k - 1)
  end
end
6
Jack Moon

En utilisant Math.gamma.floor est un moyen simple de produire une approximation, puis de l'arrondir au résultat entier correct. Devrait fonctionner pour tous les nombres entiers, inclure une vérification d'entrée si nécessaire.

3
Ayarch

Appelez simplement cette fonction

def factorial(n=0)
  (1..n).inject(:*)
end

exemples

factorial(3)
factorial(11)
3
jasonleonhard

Vous trouverez probablement un Ruby demande de fonctionnalité utile. Il contient un non trivial patch qui inclut un script Bash démo =. 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), tout en Ruby pur.

1
Martin Vahi

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
1
Nate Beers

Voici ma version qui me semble claire 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
0
Cliff Thelin

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)
0
Sky Davis

Pourquoi la bibliothèque standard exigerait-elle une méthode factorielle, alors qu'il y a un itérateur intégré à cet effet précis? Il s'appelle upto.

Non, vous n'avez pas besoin d'utiliser la récursivité, comme le montrent toutes ces autres réponses.

def fact(n)
  n == 0 ? 1 : n * fact(n - 1)
end  

Au contraire, l'itérateur intégré jusqu'à peut être utilisé pour calculer les factorielles:

factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
 => 3628800
0
Donato
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
0
Automatico

Encore une façon de le faire:

# fact(n) => Computes the Factorial of "n" = n!

def fact(n) (1..n).inject(1) {|r,i| r*i }end

fact(6) => 720
0
Robin Wood

Avec un grand respect pour tous ceux qui ont participé et ont passé leur temps à nous aider, je voudrais partager mes repères des solutions énumérées ici. Paramètres:

itérations = 1000

n = 6

                                     user     system      total        real
Math.gamma(n+1)                   0.000383   0.000106   0.000489 (  0.000487)
(1..n).inject(:*) || 1            0.003986   0.000000   0.003986 (  0.003987)
(1..n).reduce(1, :*)              0.003926   0.000000   0.003926 (  0.004023)
1.upto(n) {|x| factorial *= x }   0.003748   0.011734   0.015482 (  0.022795)

Pour n = 10

  user     system      total        real
0.000378   0.000102   0.000480 (  0.000477)
0.004469   0.000007   0.004476 (  0.004491)
0.004532   0.000024   0.004556 (  0.005119)
0.027720   0.011211   0.038931 (  0.058309)
0
Alexander Gorg