Wie generiere ich eine Zufallszahl zwischen a und b in Ruby?

189

Um beispielsweise eine Zufallszahl zwischen 3 und 10 zu generieren, verwende ich: rand(8) + 3

Gibt es eine schönere Möglichkeit, dies zu tun (so etwas wie rand(3, 10))?

Mischa Moroshko
quelle
4
def my_rand(x, y); rand(y - x) + x; end
Theo
@ Theo y - x + 1übrigens.
Nakilon
1
Versuchen Sie Ihre richtige Antwort auf 10 und 10 ** 24 als Limits: 0 wird sehr, sehr lange warten :)
xt.and.r
5
Dies funktioniert:rand(3..10)
Eikes

Antworten:

323

UPDATE: Ruby 1.9.3 Kernel#randakzeptiert auch Bereiche

rand(a..b)

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

Die Konvertierung in ein Array ist möglicherweise zu teuer und nicht erforderlich.


(a..b).to_a.sample

Oder

[*a..b].sample

Array # Beispiel

Standard in Ruby 1.8.7+.
Hinweis: wurde in 1.8.7 #choice genannt und in späteren Versionen umbenannt.

Das Generieren von Arrays erfordert jedoch Ressourcen, und die bereits geschriebene Lösung ist die beste, die Sie tun können.

Nakilon
quelle
Vielen Dank! Ich denke, ich werde bei der alten und der guten Methode bleiben :)
Misha Moroshko
32
Dies ist eine wirklich schlechte Idee, besonders wenn a und b unbekannte Größen haben. Versuchen Sie (100000000000000000..100000000000000) .to_a.sample und sehen Sie, was ich meine
:)
4
@pixelearth, wenn Sie eine bessere Idee haben, die der Frage entspricht, können Sie gerne posten.
Nakilon
rand(a..b)funktioniert nicht, es teilt sich : TypeError: can't convert Range into Integer. Es wird nicht einmal in Ruby 2.0 unterstützt
fguillen
2
@fguillen Es funktioniert für mich in 1.9.3, ich weiß nicht, warum es für Sie nicht funktioniert.
Michael Dorst
87
Random.new.rand(a..b) 

Wo aist Ihr niedrigster Wert und bist Ihr höchster Wert.

user1782571
quelle
4
Der wesentliche Unterschied zu beachten ist , dass , wenn Sie gerade nennen rand()Sie anrufen Kernel#rand, die nur ein unterstütztes maxArgument. Wenn Sie einen Bereich übergeben möchten, müssen Sie diesen verwenden Random#rand, dh Sie müssen ihn auf diese Weise implementieren. +1
Grumpit
2
sollte hinzufügen, dass das oben Gesagte für 1.9.2 gilt
grumpit
Enthält es a und b?
Abhradip
12
rand(3..10)

Kernel # rand

Wenn max ein Bereich ist, gibt rand eine Zufallszahl zurück, wobei range.member? (Number) == true ist.

Dorian
quelle
11

Beachten Sie einfach den Unterschied zwischen den Bereichsoperatoren:

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

Siehe diese Antwort: Es gibt in Ruby 1.9.2, aber nicht in früheren Versionen. Persönlich denke ich, dass Rand (8) + 3 in Ordnung ist, aber wenn Sie interessiert sind, schauen Sie sich die im Link beschriebene Zufallsklasse an.

bnaul
quelle
3

Für 10 und 10 ** 24

rand(10**24-10)+10
xt.and.r
quelle
3
oder einfachrand(10..10**24)
Michael Dorst
3
def random_int(min, max)
    rand(max - min) + min
end
Chaseph
quelle
2

Und hier ist ein kurzer Maßstab für beide #sampleund #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)

Tun rand(a..b)ist also das Richtige

Vadym Tyemirov
quelle