Come generare un numero casuale tra aeb in Ruby?


189

Per generare un numero casuale compreso tra 3 e 10, ad esempio, utilizzo: rand(8) + 3

C'è un modo migliore per farlo (qualcosa del genere rand(3, 10))?


4
def my_rand(x, y); rand(y - x) + x; end
Theo

A proposito, y - x + 1a proposito.
Nakilon,

1
Prova la tua risposta corretta su 10 e 10 ** 24 come limiti: 0 sarà molto a lungo in attesa :)
Sayan Malakshinov,

5
Funziona così:rand(3..10)
esempio il

Risposte:


324

AGGIORNAMENTO: Ruby 1.9.3 Kernel#randaccetta anche intervalli

rand(a..b)

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

La conversione in array può essere troppo costosa ed è inutile.


(a..b).to_a.sample

O

[*a..b].sample

Array # campione

Standard in Ruby 1.8.7+.
Nota: è stato nominato #Choice in 1.8.7 e ribattezzato nelle versioni successive.

Ma comunque, generare array ha bisogno di risorse e la soluzione che hai già scritto è la migliore che puoi fare.


Grazie! Penso che starò con il vecchio e il buon metodo :)
Misha Moroshko il

32
Questa è una pessima idea, soprattutto se la tua aeb sono di dimensioni sconosciute. Prova (100000000000000000..100000000000000) .to_a.sample e vedi cosa intendo
:)

4
@pixelearth, se hai un'idea migliore, che soddisfa la domanda, sei il benvenuto a postare.
Nakilon,

rand(a..b)non funziona, si divide: TypeError: can't convert Range into Integer. Non è nemmeno supportato in Ruby 2.0
fguillen il

2
@fguillen Funziona per me in 1.9.3, non so perché non funziona per te.
Michael Dorst,

87
Random.new.rand(a..b) 

Dov'è ail valore più basso ed bè il valore più alto.


4
La differenza importante da notare è che se chiami semplicemente rand()stai chiamando Kernel#rand, il che supporta solo un maxargomento. Se vuoi superare un intervallo, devi usare Random#rand, nel senso che devi implementare in questo modo. +1
scontroso

2
dovrebbe aggiungere che quanto sopra si applica a 1.9.2
grumpit

include aeb?
Abhradip,

12
rand(3..10)

Kernel # rand

Quando max è un intervallo, rand restituisce un numero casuale in cui range.member? (Numero) == vero.


11

Basta notare la differenza tra gli operatori della gamma:

3..10  # includes 10
3...10 # doesn't include 10

3

Vedi questa risposta: c'è in Ruby 1.9.2, ma non nelle versioni precedenti. Personalmente penso che rand (8) + 3 vada bene, ma se sei interessato controlla la classe Random descritta nel link.



3
def random_int(min, max)
    rand(max - min) + min
end

2

Ed ecco un rapido benchmark per entrambi #samplee #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)

Quindi, fare rand(a..b)è la cosa giusta

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.