Bagaimana cara membuat angka acak antara a dan b di Ruby?

189

Untuk menghasilkan angka acak antara 3 dan 10, misalnya, saya menggunakan: rand(8) + 3

Apakah ada cara yang lebih baik untuk melakukan ini (sesuatu seperti rand(3, 10))?

Misha Moroshko
sumber
4
def my_rand(x, y); rand(y - x) + x; end
Theo
@Theo,, y - x + 1omong-omong.
Nakilon
1
Coba jawaban Anda yang benar pada 10 dan 10 ** 24 sebagai batasan: 0 akan sangat lama menunggu :)
Sayan Malakshinov
5
Ini berfungsi:rand(3..10)
eikes

Jawaban:

324

UPDATE: Ruby 1.9.3 Kernel#randjuga menerima rentang

rand(a..b)

http://www.rubyinside.com/ruby-1-9-3-introduction-and-changes-5428.html

Konversi ke array mungkin terlalu mahal, dan itu tidak perlu.


(a..b).to_a.sample

Atau

[*a..b].sample

Array # sample

Standar dalam Ruby 1.8.7+.
Catatan: diberi nama #choice di 1.8.7 dan diganti namanya di versi yang lebih baru.

Tapi bagaimanapun, menghasilkan sumber daya array perlu, dan solusi yang sudah Anda tulis adalah yang terbaik, yang bisa Anda lakukan.

Nakilon
sumber
Terima kasih! Saya pikir saya akan tetap dengan yang lama dan metode yang baik :)
Misha Moroshko
32
Ini adalah ide yang sangat buruk, terutama jika a dan b Anda memiliki ukuran yang tidak diketahui. Coba (100000000000000000..10000000000000000) .to_a.sample dan lihat apa yang saya maksud
:)
4
@ Pixixarth, jika Anda memiliki ide yang lebih baik, yang sesuai dengan pertanyaan, Anda dipersilakan untuk memposting.
Nakilon
rand(a..b)tidak bekerja, itu membagi: TypeError: can't convert Range into Integer. Itu bahkan tidak didukung di Ruby 2.0
fguillen
2
@ fguillen Ini berfungsi untuk saya di 1.9.3, saya tidak tahu mengapa itu tidak berhasil untuk Anda.
Michael Dorst
87
Random.new.rand(a..b) 

Di mana anilai terendah Anda dan badalah nilai tertinggi Anda.

pengguna1782571
sumber
4
Perbedaan penting yang perlu diperhatikan adalah bahwa jika Anda baru saja menelepon, rand()Anda Kernel#randhanya mendukung maxargumen. Jika Anda ingin melewati rentang, Anda harus menggunakan Random#rand, artinya Anda harus menerapkan cara ini. +1
grumpit
2
harus menambahkan bahwa hal di atas berlaku untuk 1.9.2
grumpit
apakah itu termasuk a dan b?
Abhradip
12
rand(3..10)

Kernel # rand

Ketika maks adalah Range, rand mengembalikan angka acak di mana range.member? (Number) == true.

Dorian
sumber
11

Perhatikan perbedaan antara operator jangkauan:

3..10  # includes 10
3...10 # doesn't include 10
Yaniv Preiss
sumber
3

Lihat jawaban ini : ada di Ruby 1.9.2, tetapi tidak di versi sebelumnya. Secara pribadi saya pikir rand (8) + 3 baik-baik saja, tetapi jika Anda tertarik lihatlah kelas Acak yang dijelaskan dalam tautan.

bnaul
sumber
3

Untuk 10 dan 10 ** 24

rand(10**24-10)+10
Sayan Malakshinov
sumber
3
atau hanyarand(10..10**24)
Michael Dorst
3
def random_int(min, max)
    rand(max - min) + min
end
Chaseph
sumber
2

Dan berikut ini adalah patokan cepat untuk keduanya #sampledan #rand:

irb(main):014:0* Benchmark.bm do |x|
irb(main):015:1*   x.report('sample') { 1_000_000.times { (1..100).to_a.sample } }
irb(main):016:1>   x.report('rand') { 1_000_000.times { rand(1..100) } }
irb(main):017:1> end
       user     system      total        real
sample  3.870000   0.020000   3.890000 (  3.888147)
rand  0.150000   0.000000   0.150000 (  0.153557)

Jadi, melakukan rand(a..b)adalah hal yang benar

Vadym Tyemirov
sumber