Un entier aléatoire de min à max
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.