ミニからマックスのランダム整数
重要度: 2
randomInteger(min, max)関数を作成します。これは、可能な値としてminとmaxを両方含む、minからmaxへのランダムな整数数を生成します。
min..maxの間の数値はすべて同じ確率で表示される必要があります。
動作の例
alert( randomInteger(1, 5) ); // 1
alert( randomInteger(1, 5) ); // 3
alert( randomInteger(1, 5) ); // 5
前のタスクの解決策をベースとして使用できます。
単純だが間違った解決策
最も単純だが間違った解決策は、minからmaxまでの数値を生成し、切り捨てることです
function randomInteger(min, max) {
let rand = min + Math.random() * (max - min);
return Math.round(rand);
}
alert( randomInteger(1, 3) );
関数は機能しますが、正しくありません。エッジ値minとmaxを取得する確率は、他の値よりも2倍低くなります。
上記の例を何度も実行すると、2が最も頻繁に表示されることがわかります。
これは、Math.round()が間隔1..3からランダムな数値を取得し、次のように切り捨てるためです
values from 1 ... to 1.4999999999 become 1
values from 1.5 ... to 2.4999999999 become 2
values from 2.5 ... to 2.9999999999 become 3
ここで、1は2よりも2倍少ない値を取得することが明確にわかります。3でも同じです。
正しい解決策
タスクには多くの正しい解決策があります。その1つは、インターバルの境界線を調整することです。同じインターバルを確保するには、0.5から3.5の値を生成し、必要な確率をエッジに追加することができます
function randomInteger(min, max) {
// now rand is from (min-0.5) to (max+0.5)
let rand = min - 0.5 + Math.random() * (max - min + 1);
return Math.round(rand);
}
alert( randomInteger(1, 3) );
別の方法は、minからmax+1までのランダム数値にMath.floorを使用することです
function randomInteger(min, max) {
// here rand is from min to (max+1)
let rand = min + Math.random() * (max + 1 - min);
return Math.floor(rand);
}
alert( randomInteger(1, 3) );
すべての範囲がこの方法でマッピングされました。
values from 1 ... to 1.9999999999 become 1
values from 2 ... to 2.9999999999 become 2
values from 3 ... to 3.9999999999 become 3
すべての範囲の長さは同じであり、最終的な分布が均一になります。