Jak wygenerować losową liczbę między aib w Ruby?

189

Na przykład, aby wygenerować losową liczbę od 3 do 10, używam: rand(8) + 3

Czy jest na to lepszy sposób (coś takiego rand(3, 10))?

Misza Moroszko
źródło
4
def my_rand(x, y); rand(y - x) + x; end
Theo,
@ Nawiasem mówiąc, Theo y - x + 1.
Nakilon,
1
Spróbuj wpisać poprawną odpowiedź na 10 i 10 ** 24 jako limity: 0 będzie bardzo długo czekać :)
Sayan Malakshinov
5
Działa to:rand(3..10)
Eikes

Odpowiedzi:

324

AKTUALIZACJA: Ruby 1.9.3 Kernel#randakceptuje również zakresy

rand(a..b)

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

Konwersja na tablicę może być zbyt droga i nie jest konieczna.


(a..b).to_a.sample

Lub

[*a..b].sample

Array # sample

Standard w Ruby 1.8.7+.
Uwaga: w 1.8.7 został nazwany # wybór i w późniejszych wersjach przemianowany.

Ale i tak generowanie macierzy wymaga zasobów, a rozwiązanie, które już napisałeś, jest najlepsze, co możesz zrobić.

Nakilon
źródło
Dzięki! Myślę, że pozostanę przy starej i dobrej metodzie :)
Misha Moroshko,
32
To naprawdę zły pomysł, szczególnie jeśli twoje aib mają nieznane rozmiary. Spróbuj (100000000000000000..100000000000000) .to_a.sample i zobacz, co mam na myśli
:)
4
@pixelearth, jeśli masz lepszy pomysł, który odpowiada na pytanie, możesz pisać.
Nakilon,
rand(a..b)nie działa, to dzieli: TypeError: can't convert Range into Integer. Nie jest nawet obsługiwany w Ruby 2.0
fguillen,
2
@fguillen Działa dla mnie w wersji 1.9.3, nie wiem, dlaczego to nie działa dla ciebie.
Michael Dorst,
87
Random.new.rand(a..b) 

Gdzie ajest twoja najniższa wartość i bnajwyższa wartość.

użytkownik1782571
źródło
4
Ważną różnicą do zapamiętania jest to, że jeśli po prostu dzwonisz rand(), to dzwonisz Kernel#rand, co obsługuje tylko maxargument. Jeśli chcesz przekroczyć zakres, musisz użyć Random#rand, co oznacza, że ​​musisz wdrożyć w ten sposób. +1
grumpit
2
należy dodać, że powyższe stosuje się do 1.9.2
grumpit
czy zawiera a i b?
Abhradip
12
rand(3..10)

Jądro # rand

Gdy maks. To Zakres, rand zwraca losową liczbę, gdzie range.member? (Liczba) == true.

dorycki
źródło
11

Zwróć uwagę na różnicę między operatorami zakresu:

3..10  # includes 10
3...10 # doesn't include 10
Yaniv Preiss
źródło
3

Zobacz odpowiedź: jest w Ruby 1.9.2, ale nie we wcześniejszych wersjach. Osobiście uważam, że rand (8) + 3 jest w porządku, ale jeśli jesteś zainteresowany, sprawdź klasę Random opisaną w linku.

bnaul
źródło
3

Dla 10 i 10 ** 24

rand(10**24-10)+10
Sayan Malakshinov
źródło
3
lub po prosturand(10..10**24)
Michael Dorst,
3
def random_int(min, max)
    rand(max - min) + min
end
Chaseph
źródło
2

Oto szybki punkt odniesienia zarówno dla, jak #samplei dla #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)

Więc robienie rand(a..b)jest właściwą rzeczą

Wadym Tyemirow
źródło