Aku jadi gila: Di mana fungsi Ruby untuk faktorial? Tidak, saya tidak memerlukan implementasi tutorial, saya hanya ingin fungsi dari perpustakaan. Ini bukan di Matematika!
Saya mulai ragu, apakah ini fungsi perpustakaan standar?
Aku jadi gila: Di mana fungsi Ruby untuk faktorial? Tidak, saya tidak memerlukan implementasi tutorial, saya hanya ingin fungsi dari perpustakaan. Ini bukan di Matematika!
Saya mulai ragu, apakah ini fungsi perpustakaan standar?
(1..6).inject(:*)yang lebih ringkas.
(1..num).inject(:*)gagal untuk kasus di mana num == 0. (1..(num.zero? ? 1 : num)).inject(:*)memberikan jawaban yang benar untuk kasus 0 dan mengembalikan niluntuk parameter negatif.
Jawaban:
Tidak ada fungsi faktorial di perpustakaan standar.
Math.gammametode, misalnya stackoverflow.com/a/37352690/407213
Seperti ini lebih baik
(1..n).inject(:*) || 1
(1..n).reduce(1, :*).
Ini tidak ada di pustaka standar tetapi Anda dapat memperluas kelas 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
Faktorial berulang NB adalah pilihan yang lebih baik untuk alasan kinerja yang jelas.
Tanpa malu-malu dikutip dari http://rosettacode.org/wiki/Factorial#Ruby , favorit pribadi saya adalah
class Integer
def fact
(1..self).reduce(:*) || 1
end
end
>> 400.fact
=> 64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Implementasi ini juga merupakan yang tercepat di antara varian yang terdaftar di Rosetta Code.
Ditambahkan || 1untuk menangani kasus nol.
Dengan terima kasih dan penghargaan kepada Mark Thomas , berikut adalah versi yang sedikit lebih efisien, elegan, dan tidak jelas:
class Integer
def fact
(2..self).reduce(1,:*)
end
end
reduce: (1..self).reduce(1,:*).
(2..self).reduce(1,:*), jika efisiensi mikro adalah hal Anda :)
Dalam matematika, factorial of nhanya gamma function of n+1
(lihat: http://en.wikipedia.org/wiki/Gamma_function )
Ruby Math.gamma()hanya menggunakan Math.gamma(n+1)dan melemparkannya kembali ke integer jika diinginkan.
Anda juga bisa menggunakan Math.gammafungsi yang bermuara pada faktorial untuk parameter integer.
0..22: MRI Ruby sebenarnya melakukan pencarian untuk nilai-nilai itu (lihat static const double fact_table[]di sumber ). Di luar itu, itu adalah perkiraan. 23 !, misalnya, membutuhkan mantissa 56-bit yang tidak mungkin direpresentasikan secara tepat menggunakan IEEE 754 double yang memiliki mantisa 53-bit.
class Integer
def !
(1..self).inject(:*)
end
end
!3 # => 6
!4 # => 24
class Integer ; def ! ; (1..self).inject(:*) ; end ; end?
akebetulan terjadi Integerdalam kasus !a... melakukan hal itu dapat menyebabkan ada bug yang sangat sulit untuk diceritakan. Jika akebetulan jumlahnya besar seperti 357264543maka prosesor akan berputar besar dan orang mungkin bertanya-tanya mengapa program tiba-tiba menjadi lambat
def factorial(n=0)
(1..n).inject(:*)
end
factorial(3)
factorial(11)
Menggunakan Math.gamma.flooradalah cara mudah untuk menghasilkan perkiraan dan kemudian membulatkannya kembali ke hasil bilangan bulat yang benar. Harus berfungsi untuk semua Integer, sertakan pemeriksaan input jika perlu.
n = 22berhenti memberikan jawaban yang tepat dan menghasilkan perkiraan.
Dengan rasa hormat yang tinggi kepada semua yang berpartisipasi dan menghabiskan waktu mereka untuk membantu kami, saya ingin membagikan tolok ukur saya dari solusi yang tercantum di sini. Parameter:
iterasi = 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)
Untuk 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)
Math.gamma(n+1)juga hanya perkiraan untuk n> 22, jadi mungkin tidak cocok untuk semua kasus penggunaan.
Hanya cara lain untuk melakukannya, meskipun sebenarnya tidak perlu.
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
Anda mungkin akan menemukan permintaan fitur Ruby berguna. Ini berisi patch nontrivial yang menyertakan skrip Bash demo . Perbedaan kecepatan antara loop naif dan solusi yang disajikan dalam batch secara harfiah bisa 100x (seratus kali lipat). Ditulis dengan Ruby murni.
Ini adalah versi saya yang tampaknya jelas bagi saya meskipun tidak sebersih itu.
def factorial(num)
step = 0
(num - 1).times do (step += 1 ;num *= step) end
return num
end
Ini adalah garis pengujian irb saya yang menunjukkan setiap langkah.
num = 8;step = 0;(num - 1).times do (step += 1 ;num *= step; puts num) end;num
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
Satu cara lagi untuk melakukannya:
# fact(n) => Computes the Factorial of "n" = n!
def fact(n) (1..n).inject(1) {|r,i| r*i }end
fact(6) => 720
Mengapa pustaka standar memerlukan metode faktorial, bila ada iterator bawaan untuk tujuan yang tepat ini? Itu disebut upto.
Tidak, Anda tidak perlu menggunakan rekursi, seperti yang ditunjukkan oleh semua jawaban lainnya.
def fact(n)
n == 0 ? 1 : n * fact(n - 1)
end
Sebaliknya, iterator bawaan upto dapat digunakan untuk menghitung faktorial:
factorial = 1
1.upto(10) {|x| factorial *= x }
factorial
=> 3628800
6.downto(1).inject(:*)