足し合わせるとNになるM個の乱数を生成する【JS】



問題:足し合わせるとNになるM個の乱数をどのように生成しますか?



NとかMとかちょっとわかりにくいですが、例えば100%をランダムな数値で4つに分割するにはどうするか、みたいな問題です。

簡単だと思ってたら、意外と少し頭を使ったので、一手順例のメモとして残しておこうと思います。




最初にどのような手順で実現するかを記した後に、Javascriptで実装してみます。





実現したいもの

実現したいものは下記のように、例えば合計すると毎回100になるような乱数を4つ生成するプログラムです。
※3秒ごとに切り替わります。





手順

おそらく、実現方法はたくさんあると思うのですが、今回は下記のような手順を考えました。

①変数を用意

乱数をいくつ生成するか = 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個の乱数を生成する機能のデモを用意しました。

= 生成する乱数の個数(M)
= 合計値(N)
= 一つの乱数の最大値(O)





以上、足し合わせるとNになるM個の乱数を生成する方法でした!

問題点、改善点、別案などなどありましたら、コメント頂けると嬉しいです!

コメント

タイトルとURLをコピーしました