¿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))?

Misha Moroshko
fuente
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.

Nakilon
fuente
¡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?

usuario1782571
fuente
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.

dorio
fuente
11

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

3..10  # includes 10
3...10 # doesn't include 10
Yaniv Preiss
fuente
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.

bnaul
fuente
3

Para 10 y 10 ** 24

rand(10**24-10)+10
xt.and.r
fuente
3
o simplementerand(10..10**24)
Michael Dorst
3
def random_int(min, max)
    rand(max - min) + min
end
Chaseph
fuente
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

Vadym Tyemirov
fuente