804 votes

Comment obtenir un nombre aléatoire en Ruby

Comment générer un nombre aléatoire entre 0 y n ?

1 votes

Utilisation de srand <some_number> avant d'écrire rand vous donnera une séquence pseudo-aléatoire déterministe (c'est-à-dire répétable), si vous en avez besoin. ruby-doc.org/core-2.5.6/Random.html#method-c-srand

966voto

VonC Points 414372

Utilisez rand(range)

Desde Numéros aléatoires de Ruby :

Si vous aviez besoin d'un nombre entier aléatoire pour simuler le lancer d'un dé à six faces, vous utiliseriez : 1 + rand(6) . Un jet de dés au craps pourrait être simulé avec 2 + rand(6) + rand(6) .

Enfin, si vous avez juste besoin d'un flottant aléatoire, il suffit d'appeler rand sans aucun argument.


Comme Marc-André Lafortune mentions dans sa réponse ci-dessous (allez la voter) , Ruby 1.9.2 possède sa propre Random classe (que Marc-André lui-même a aidé à déboguer d'où le 1.9.2 cible pour cette fonctionnalité).

Par exemple, dans ce jeu où vous devez deviner 10 numéros vous pouvez les initialiser avec :

10.times.map{ 20 + Random.rand(11) } 
#=> [26, 26, 22, 20, 30, 26, 23, 23, 25, 22]

Note :

C'est pourquoi l'équivalent de Random.new.rand(20..30) serait 20 + Random.rand(11) puisque Random.rand(int) renvoie "un nombre entier aléatoire supérieur ou égal à zéro et moins que l'argument ." 20..30 comprend 30, je dois trouver un nombre aléatoire entre 0 et 11, en excluant 11.

2 votes

N'est-ce pas terriblement non-rubain ? Je pensais que tout était un objet, la moindre surprise et que...

1 votes

@yar : C'est un peu "perlish". Maintenant Ruby a sa classe Random (voir ma réponse).

3 votes

@VonC : C'est bien que vous ayez modifié votre réponse pour mentionner le nouveau Random mais c'est une mauvaise idée d'appeler Random.new plusieurs fois comme dans votre exemple. J'ai modifié ma réponse pour le préciser.

598voto

Bien que vous puissiez utiliser rand(42-10) + 10 pour obtenir un nombre aléatoire entre 10 y 42 (où 10 est inclusif et 42 exclusif), il existe une meilleure méthode depuis Ruby 1.9.3, où il est possible d'appeler :

rand(10...42) # => 13

Disponible pour toutes les versions de Ruby en nécessitant mon backports gemme.

Ruby 1.9.2 a également introduit la fonction Random afin que vous puissiez créer vos propres objets de générateur de nombres aléatoires et dispose d'une API intéressante :

r = Random.new
r.rand(10...42) # => 22
r.bytes(3) # => "rnd"

El Random La classe elle-même agit comme un générateur aléatoire, donc vous appelez directement :

Random.rand(10...42) # => same as rand(10...42)

Notes sur Random.new

Dans la plupart des cas, le plus simple est d'utiliser rand o Random.rand . Créer un nouveau générateur aléatoire chaque fois que vous voulez un nombre aléatoire est une très mauvaise idée . Si vous faites cela, vous obtiendrez les propriétés aléatoires de l'algorithme d'ensemencement initial, qui sont atroces par rapport aux propriétés de l'algorithme d'ensemencement initial. le générateur aléatoire lui-même .

Si vous utilisez Random.new vous devriez donc l'appeler le plus rarement possible par exemple une fois comme MyApp::Random = Random.new et l'utiliser partout ailleurs.

Les cas où Random.new est utile sont les suivants :

  • vous écrivez une gemme et ne voulez pas interférer avec la séquence de rand / Random.rand que les programmes principaux pourraient s'appuyer sur
  • vous voulez des séquences reproductibles distinctes de nombres aléatoires (disons une par fil)
  • vous voulez pouvoir sauvegarder et reprendre une séquence reproductible de nombres aléatoires (c'est aussi simple que cela). Random peuvent être marshallés)

1 votes

Excellent ! +1. J'ai complété ma propre réponse pour refléter cette nouvelle fonctionnalité (et mentionner votre contribution avec le Bug #3104 ;) ).

1 votes

@yar : Mon backports gem est simplement une collection de méthodes qui sont nouvelles dans RUby 1.8.7, 1.9.1, 1.9.2, mais implémentées en Ruby. J'utilise RubySpec pour m'assurer que les résultats sont compatibles avec Ruby.

0 votes

@Marc-André Lafortune, merci pour ça. J'ai toujours trouvé étrange la quantité de Ruby qui est implémentée en non-Ruby (C ou autre) pour des raisons de vitesse. Mais ce sont les ruptures

46voto

Thomas Fankhauser Points 1899

Si vous ne cherchez pas seulement un nombre mais aussi un hex ou un uuid, il est bon de mentionner que la fonction SecureRandom a trouvé son chemin depuis ActiveSupport au noyau ruby dans la version 1.9.2+. Donc sans avoir besoin d'un framework complet :

require 'securerandom'

p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88

p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409

p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"

C'est documenté ici : Ruby 1.9.3 - Module : SecureRandom (lib/securerandom.rb)

0 votes

Et si vous avez besoin d'un numéro aléatoire à 4 chiffres ?

1 votes

Onurozgurozkan je présume SecureRandom.random_number(1000..9999)

1 votes

SecureRandom.random_number() ne prend pas de gamme, donc non. Vous voudriez probablement quelque chose comme SecureRandom.random_number(10_000) (pour 0-9999) ou SecureRandom.random_number(9_000)+1_000 (pour 1000-9999).

38voto

Vous pouvez générer un nombre aléatoire avec la fonction rand méthode. L'argument passé à la méthode rand devrait être une méthode integer ou un range et renvoie un nombre aléatoire correspondant dans la plage :

rand(9)       # this generates a number between 0 to 8
rand(0 .. 9)  # this generates a number between 0 to 9
rand(1 .. 50) # this generates a number between 1 to 50
#rand(m .. n) # m is the start of the number range, n is the end of number range

0 votes

Je pense qu'utiliser votre rand(1..6) se lit plus clairement que la première réponse rand(6)+1 .

22voto

Mark A. Nicolosi Points 11859

Eh bien, j'ai trouvé. Apparemment, il y a une fonction intégrée ( ?) appelée rand :

rand(n + 1)

Si quelqu'un répond avec une réponse plus détaillée, je la marquerai comme étant la bonne réponse.

2 votes

Oui, il est intégré dans le module Kernel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X