Comment générer un nombre aléatoire entre a et b dans Ruby?

189

Pour générer un nombre aléatoire entre 3 et 10, par exemple, j'utilise: rand(8) + 3

Y a-t-il une meilleure façon de faire cela (quelque chose comme rand(3, 10))?

Misha Moroshko
la source
4
def my_rand(x, y); rand(y - x) + x; end
Theo
@Theo, y - x + 1au fait.
Nakilon
1
Essayez votre bonne réponse le 10 et le 10 ** 24 comme limites: 0 sera très très long :)
Sayan Malakshinov
5
Cela fonctionne:rand(3..10)
eikes

Réponses:

324

MISE À JOUR: Ruby 1.9.3 Kernel#randaccepte également les plages

rand(a..b)

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

La conversion en matrice peut être trop coûteuse et inutile.


(a..b).to_a.sample

Ou

[*a..b].sample

Array # sample

Standard dans Ruby 1.8.7+.
Remarque: a été nommé #choice dans la 1.8.7 et renommé dans les versions ultérieures.

Mais de toute façon, la génération d'un tableau nécessite des ressources, et la solution que vous avez déjà écrite est la meilleure que vous puissiez faire.

Nakilon
la source
Merci! Je pense que je vais rester avec l'ancienne et la bonne méthode :)
Misha Moroshko
32
C'est une très mauvaise idée, surtout si vos a et b sont de tailles inconnues. Essayez (100000000000000000..100000000000000) .to_a.sample et voyez ce que je veux dire
:)
4
@pixelearth, si vous avez une meilleure idée de ce qui correspond à la question, vous êtes invités à poster.
Nakilon le
rand(a..b)ne fonctionne pas, il se divise: TypeError: can't convert Range into Integer. Il n'est même pas pris en charge dans Ruby 2.0
fguillen
2
@fguillen Cela fonctionne pour moi dans la version 1.9.3, je ne sais pas pourquoi cela ne fonctionne pas pour vous.
Michael Dorst
87
Random.new.rand(a..b) 

aest votre valeur la plus basse et bvotre valeur la plus élevée.

user1782571
la source
4
La différence importante à noter est que si vous appelez simplement, rand()vous appelez Kernel#rand, ce qui ne prend en charge qu'un maxargument. Si vous voulez passer une plage, vous devez utiliser Random#rand, ce qui signifie que vous devez implémenter de cette façon. +1
grumpit
2
devrait ajouter que ce qui précède s'applique à 1.9.2
grumpit
comprend-il a et b?
Abhradip
12
rand(3..10)

Noyau # rand

Lorsque max est un Range, rand renvoie un nombre aléatoire où range.member? (Number) == true.

Dorian
la source
11

Notez simplement la différence entre les opérateurs de plage:

3..10  # includes 10
3...10 # doesn't include 10
Yaniv Preiss
la source
3

Voir cette réponse: il y en a dans Ruby 1.9.2, mais pas dans les versions antérieures. Personnellement, je pense que rand (8) + 3 est bien, mais si vous êtes intéressé, consultez la classe Random décrite dans le lien.

bnaul
la source
3

Pour 10 et 10 ** 24

rand(10**24-10)+10
Sayan Malakshinov
la source
3
ou tout simplementrand(10..10**24)
Michael Dorst
3
def random_int(min, max)
    rand(max - min) + min
end
Chaseph
la source
2

Et voici une référence rapide pour les deux #sampleet #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)

Alors, faire rand(a..b)est la bonne chose

Vadym Tyemirov
la source