Reputation: 2355
I'm going crazy: Where is the Ruby function for factorial? No, I don't need tutorial implementations, I just want the function from the library. It's not in Math!
I'm starting to doubt, is it a standard library function?
Upvotes: 100
Views: 83162
Reputation: 24412
It's not in the standard library but you can extend the Integer class.
class Integer
def factorial_recursive
self <= 1 ? 1 : self * (self - 1).factorial_recursive
end
def factorial_iterative
f = 1; for i in 1..self; f *= i; end; f
end
alias :factorial :factorial_iterative
end
N.B. Iterative factorial is a better choice for obvious performance reasons.
Upvotes: 78
Reputation: 603
In Ruby standard library function for factorial is not available. We can make a simple function of factorial in ruby in this way.
def factorial_number(n)
if n <= 1
1
else
n * factorial_number(n-1)
end
end
puts factorial_number(6) #Output is 720 => (6*5*4*3*2*1)
puts factorial_number(8) #Output is 40320 => (8*7*6*5*4*3*2*1)
Upvotes: 0
Reputation: 1078
With high respect to all who participated and spent their time to help us, I would like to share my benchmarks of the solutions listed here. Params:
iterations = 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)
For 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)
Upvotes: 5
Reputation: 9437
Why would the standard library require a factorial method, when there is a built-in iterator for this exact purpose? It is called upto
.
No you do not need to use recursion, like all these other answers show.
def fact(n)
n == 0 ? 1 : n * fact(n - 1)
end
Rather, the built-in iterator upto can be used to calculate factorials:
factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
=> 3628800
Upvotes: 1
Reputation: 35219
Shamelessly cribbed from http://rosettacode.org/wiki/Factorial#Ruby, my personal favorite is
class Integer
def fact
(1..self).reduce(:*) || 1
end
end
>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
This implementation also happens to be the fastest among the variants listed in Rosetta Code.
Added || 1
to handle the zero case.
With thanks and appreciation to Mark Thomas, here's a version that is a bit more efficient, elegant and obscure:
class Integer
def fact
(2..self).reduce(1,:*)
end
end
Upvotes: 29
Reputation: 41
Just one more way to do it:
# fact(n) => Computes the Factorial of "n" = n!
def fact(n) (1..n).inject(1) {|r,i| r*i }end
fact(6) => 720
Upvotes: 0
Reputation: 13907
class Integer
def !
(1..self).inject(:*)
end
end
!3 # => 6
!4 # => 24
Upvotes: 14
Reputation: 17902
In math, factorial of n
is just the gamma function of n+1
(see: http://en.wikipedia.org/wiki/Gamma_function)
Ruby has Math.gamma()
so just use Math.gamma(n+1)
and cast it back to an integer if desired.
Upvotes: 21
Reputation: 61
Here is my version seems to be clear to me even though it's not as clean.
def factorial(num)
step = 0
(num - 1).times do (step += 1 ;num *= step) end
return num
end
This was my irb testing line that showed each step.
num = 8;step = 0;(num - 1).times do (step += 1 ;num *= step; puts num) end;num
Upvotes: 1
Reputation: 13907
def factorial(n=0)
(1..n).inject(:*)
end
factorial(3)
factorial(11)
Upvotes: 4
Reputation: 139
You will probably find a Ruby feature request useful. It contains a nontrivial patch that includes a demo Bash script. The speed difference between a naive loop and the solution presented in the batch can be literally 100x (hundred fold). Written all in pure Ruby.
Upvotes: 1
Reputation: 3
And yet another way (=
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)
Upvotes: 0
Reputation: 1425
Just another way to do it, although it really isn't necessary.
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
Upvotes: 1
Reputation: 31
Using Math.gamma.floor
is an easy way to produce an approximation and then round it back down to the correct integer result. Should work for all Integers, include an input check if necessary.
Upvotes: 3
Reputation: 12926
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
Upvotes: 0
Reputation: 61
I just wrote my own:
def fact(n)
if n<= 1
1
else
n * fact( n - 1 )
end
end
Also, you can define a falling factorial:
def fall_fact(n,k)
if k <= 0
1
else
n*fall_fact(n - 1, k - 1)
end
end
Upvotes: 6
Reputation: 151
You could also use Math.gamma
function which boils down to factorial for integer parameters.
Upvotes: 14