retour au cours

Un entier aléatoire de min à max

importance: 2

Créez une fonction randomInteger(min, max) qui génère un nombre entier aléatoire compris entre min et max (min et max inclut).

Tout nombre compris dans l’intervalle min..max doit apparaître avec la même probabilité.

Quelques exemples :

alert( randomInteger(1, 5) ); // 1
alert( randomInteger(1, 5) ); // 3
alert( randomInteger(1, 5) ); // 5

Vous pouvez utiliser la solution de la tâche précédente comme base.

La solution simple mais fausse

La solution la plus simple mais fausse serait de générer une valeur de min à max et de l’arrondir :

function randomInteger(min, max) {
  let rand = min + Math.random() * (max - min);
  return Math.round(rand);
}

alert( randomInteger(1, 3) );

La fonction marche, mais elle est incorrecte. La probabilité d’obtenir les valeurs min et max est deux fois inférieure à toute autre.

Si vous exécutez l’exemple ci-dessous plusieurs fois, vous verrez facilement que 2 apparaît le plus souvent.

Cela se produit car Math.round() obtient des nombres aléatoires à partir de l’intervalle 1..3 et les arrondit comme ici :

values from 1    ... to 1.4999999999  devient 1
values from 1.5  ... to 2.4999999999  devient 2
values from 2.5  ... to 2.9999999999  devient 3

Maintenant, nous pouvons clairement voir que 1 obtient deux fois moins de valeurs que 2. Et la même chose avec 3.

La bonne solution

Il existe de nombreuses solutions correctes à la tâche. L’une d’elles consiste à ajuster les limites d’intervalle. Pour garantir les mêmes intervalles, nous pouvons générer des valeurs comprises entre 0.5 et 3.5, ajoutant ainsi les probabilités requises :

function randomInteger(min, max) {
  // maintenant rand est entre (min-0.5) et (max+0.5)
  let rand = min - 0.5 + Math.random() * (max - min + 1);
  return Math.round(rand);
}

alert( randomInteger(1, 3) );

Une autre solution pourrait être d’utiliser Math.floor pour un nombre aléatoie compris entre min et max+1.

function randomInteger(min, max) {
  // ici rand est de min à (max+1)
  let rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

alert( randomInteger(1, 3) );

Maintenant, tous les intervalles sont mappés de cette façon :

values from 1  ... to 1.9999999999  devient 1
values from 2  ... to 2.9999999999  devient 2
values from 3  ... to 3.9999999999  devient 3

Tous les intervalles ont la même longueur, rendant la distribution finale uniforme.