Como gerar um número aleatório entre aeb no Ruby?

189

Para gerar um número aleatório entre 3 e 10, por exemplo, eu uso: rand(8) + 3

Existe uma maneira melhor de fazer isso (algo como rand(3, 10))?

Misha Moroshko
fonte
4
def my_rand(x, y); rand(y - x) + x; end
Theo
@ Theo, y - x + 1a propósito.
Nakilon
1
Tentar a sua resposta correta em 10 e 10 ** 24 como limites: 0 será muito, muito longa awaitng :)
xt.and.r
5
Isso funciona:rand(3..10)
eikes

Respostas:

323

UPDATE: Ruby 1.9.3 Kernel#randtambém aceita intervalos

rand(a..b)

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

A conversão em array pode ser muito cara e desnecessária.


(a..b).to_a.sample

Ou

[*a..b].sample

Matriz # amostra

Padrão no Ruby 1.8.7+.
Nota: foi nomeado #choice em 1.8.7 e renomeado em versões posteriores.

Mas, de qualquer forma, a geração de array precisa de recursos e a solução que você já escreveu é a melhor que você pode fazer.

Nakilon
fonte
Obrigado! Acho que vou ficar com o velho eo bom método :)
Misha Moroshko
32
Essa é uma péssima idéia, principalmente se os tamanhos a e b forem desconhecidos. Tente (100000000000000000..100000000000000) .to_a.sample e veja o que eu quero dizer
:)
4
@pixelearth, se você tem uma idéia melhor, que concorda com a pergunta, você pode postar.
Nakilon
rand(a..b)não funciona, ele divide: TypeError: can't convert Range into Integer. Nem sequer é suportado no Ruby 2.0
fguillen
2
@guguen Funciona para mim no 1.9.3, não sei por que não está funcionando para você.
Michael Dorst
87
Random.new.rand(a..b) 

Onde aestá o seu valor mais baixo e o bseu valor mais alto.

user1782571
fonte
4
A diferença importante a ser observada é que, se você acabou de ligar, rand()está ligando Kernel#rand, o que suporta apenas um maxargumento. Se você deseja passar um intervalo, precisa usar Random#rand, o que significa que você deve implementar dessa maneira. 1
grumpit
2
deve acrescentar que o acima se aplica a 1.9.2
grumpit 17/01
inclui a e b?
Abhradip
12
rand(3..10)

Kernel # rand

Quando max é um Range, rand retorna um número aleatório em que range.member? (Number) == true.

Dorian
fonte
11

Observe a diferença entre os operadores de intervalo:

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

Veja esta resposta: existe no Ruby 1.9.2, mas não nas versões anteriores. Pessoalmente, acho que rand (8) + 3 é bom, mas se você estiver interessado, confira a classe Random descrita no link.

bnaul
fonte
3

Para 10 e 10 ** 24

rand(10**24-10)+10
xt.and.r
fonte
3
ou apenas #rand(10..10**24)
22713 Michael Dorst
3
def random_int(min, max)
    rand(max - min) + min
end
Chaseph
fonte
2

E aqui está uma referência rápida para ambos #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)

Então, fazer rand(a..b)é a coisa certa

Vadym Tyemirov
fonte