問題:足し合わせるとNになるM個の乱数をどのように生成しますか?
NとかMとかちょっとわかりにくいですが、例えば100%をランダムな数値で4つに分割するにはどうするか、みたいな問題です。
簡単だと思ってたら、意外と少し頭を使ったので、一手順例のメモとして残しておこうと思います。
最初にどのような手順で実現するかを記した後に、Javascriptで実装してみます。
実現したいもの
実現したいものは下記のように、例えば合計すると毎回100になるような乱数を4つ生成するプログラムです。
※2秒ごとに切り替わります。
手順
おそらく、実現方法はたくさんあると思うのですが、今回は下記のような手順を考えました。
①変数を用意
乱数をいくつ生成するか = M
合計値をいくつにするか = N
一つの乱数の最大値 = O
もうひとつ『残数』という変数を用意して、初期値はNを代入しておきます。
この残数は生成する乱数の合計が100を超えないようにコントロールするために使用します。
②ループ開始
乱数の個数(M)だけ繰り返し文を実行させます。
③乱数を生成(ループ内)
この時下記のふたつの条件で乱数を生成する
生成する乱数は一つの乱数の最大値(O)以下になるように
残数から生成した乱数をマイナスした時に0か負の数になる場合は再生成する
④残数から生成した乱数の値をマイナスする(ループ内)
この処理により、合計値(O)までの残数を記録し続けることができます。
⑤最後のループは残数をそのまま使用(ループ内)
プログラム
上記の手順をJavascriptで実装すると下記のようになります。
上記の手順に合わせてコメントアウトを入れております。
function createRandNumsArray(M,N,O){
//1.変数を用意
let randNumAmount = M
let remain = N
let max = O
let result = []
//2.ループ開始
for(let i=1; i <= randNumAmount; i++){
if(i!=randNumAmount){
//3.乱数を生成
do {
parcent = Math.floor( Math.random() * max )
}while (Math.sign(remain - parcent) == -1 || Math.sign(remain - parcent) == 0)
//4.残数から生成した乱数の値をマイナスする
remain = remain - parcent
result.push(parcent)
}else{
//5最後のループは残数をそのまま使用
result.push(remain)
}
}
return result
}
例えば、足し合わせると100になる乱数を4個用意するには上記関数を下記のように呼び出せばよいです。
const M = 4 //生成する乱数の個数
const N = 100 //合計値
const O = 70 //一つの乱数の最大値
let randNumsArray = createRandNumsArray(M,N,O)
デモ
足し合わせるとNになるM個の乱数を生成する機能のデモを用意しました。
= 合計値(N)
= 一つの乱数の最大値(O)
以上、足し合わせるとNになるM個の乱数を生成する方法でした!
問題点、改善点、別案などなどありましたら、コメント頂けると嬉しいです!
コメント