¿Cómo generar un número aleatorio entre ayb en Ruby?


189

Para generar un número aleatorio entre 3 y 10, por ejemplo, uso: rand(8) + 3

¿Hay una mejor manera de hacer esto (algo así como rand(3, 10))?


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

@Theo, y - x + 1por cierto.
Nakilon

1
Pruebe su respuesta correcta en 10 y 10 ** 24 como límites: 0 estará muy, muy a la espera :)
xt.and.r

55
Esto funciona:rand(3..10)
eikes

Respuestas:


323

ACTUALIZACIÓN: Ruby 1.9.3 Kernel#randtambién acepta rangos

rand(a..b)

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

La conversión a matriz puede ser demasiado costosa y no es necesaria.


(a..b).to_a.sample

O

[*a..b].sample

Array # sample

Estándar en Ruby 1.8.7+.
Nota: fue nombrado #choice en 1.8.7 y renombrado en versiones posteriores.

Pero de todos modos, la generación de matriz necesita recursos, y la solución que ya escribió es lo mejor que puede hacer.


¡Gracias! Creo que me quedaré con el viejo y el buen método :)
Misha Moroshko

32
Esta es una muy mala idea, especialmente si su ayb son de tamaños desconocidos. Pruebe (100000000000000000..100000000000000) .to_a.sample y vea lo que quiero decir
:)

44
@pixelearth, si tiene una mejor idea, lo que concuerda con la pregunta, puede publicar.
Nakilon

rand(a..b)no funciona, se divide: TypeError: can't convert Range into Integer. Ni siquiera es compatible con Ruby 2.0
fguillen

2
@fguillen Me funciona en 1.9.3, no sé por qué no te funciona.
Michael Dorst

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

¿Dónde aestá su valor más bajo y bsu valor más alto?


44
La diferencia importante a tener en cuenta es que si solo llama rand(), está llamando Kernel#rand, lo que solo admite un maxargumento. Si desea pasar un rango, debe usarlo Random#rand, lo que significa que debe implementarlo de esta manera. +1
gruñón

2
debería agregar que lo anterior se aplica a 1.9.2
grumpit

¿incluye ayb?
Abhradip

12
rand(3..10)

Kernel # rand

Cuando max es un Range, rand devuelve un número aleatorio donde range.member? (Number) == true.


11

Solo tenga en cuenta la diferencia entre los operadores de rango:

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

3

Vea esta respuesta: hay en Ruby 1.9.2, pero no en versiones anteriores. Personalmente, creo que rand (8) + 3 está bien, pero si está interesado, consulte la clase Aleatoria descrita en el enlace.




2

Y aquí hay un punto de referencia rápido para ambos #sampley #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)

Entonces, hacer rand(a..b)es lo correcto

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.