JavaScriptで解くバナナ配布問題:配列を使った実装方法を解説
問題
n人が一列に並んでいるとします。この人たちに対して、次のルールに従ってバナナを配布していきます。
まず、1人目に1本、2人目に2本…というように順番に渡し、n人目にn本を渡します。
次に、列の先頭に戻り、1人目にn+1本、2人目にn+2本…というように渡し、n人目に2n本を渡します。
このプロセスを、バナナがなくなるまで繰り返します(毎回渡す本数を1本ずつ増やし、列の末尾に達したら先頭に戻ります)。途中でバナナが足りなくなった場合は、残りの本数をすべてその時点の相手に渡します。
ここで求められているのは、人数 num を第1引数、バナナの総本数 m を第2引数として受け取るJavaScript関数を作成することです。
この関数は、最終的なバナナの配布結果を表す、長さ num の配列を返す必要があります。
例えば、関数への入力が以下だったとします。
const num = 3; const m = 10;
このとき、期待される出力は次の通りです。
const output = [5, 2, 3];
出力の解説
処理の流れを順に追ってみましょう。
1回目のターンでは res[0] += 1 が実行され、配列は [1, 0, 0] になります。
2回目のターンでは res[1] += 2 が実行され、配列は [1, 2, 0] になります。
3回目のターンでは res[2] += 3 が実行され、配列は [1, 2, 3] になります。
4回目のターンでは res[0] += 4 が実行されますが、この時点で残りのバナナは4本しかないため、すべて1人目に渡されます。最終的な配列は [5, 2, 3] となります。
コード例
この問題を解くコードは以下の通りです。
const num = 3;
const m = 10;
const distributeBananas = (num = 1, m = 1) => {
const res = new Array(num).fill(0);
let curr = 1;
while(true){
for(let i = 0; i < num; i++){
if(m < curr){
res[i] += m
return res
};
res[i] += curr;
m -= curr;
curr++;
};
};
};
console.log(distributeBananas(num, m));
このコードでは、まず全員の受け取った本数を0で初期化した配列 res を用意し、次に渡す本数を表す変数 curr を1で初期化しています。無限ループの中で列を一周ずつ回り、各人に curr 本ずつ配っていきます。もし残りのバナナ数 m が curr より少なくなった時点で、残りをすべてその人に渡して結果を返します。
出力
コンソールには以下のように出力されます。
[5, 2, 3]
-
JavaScriptでランダムな数値を生成する方法|Math.random()の使い方を解説
JavaScriptのMath.random()関数は、0以上1未満の範囲でランダムな浮動小数点数を生成するために使用されます。戻り値は「0以上・1未満」であり、1自体は含まれない点に注意してください。この関数を活用すれば、サイコロのようなランダムな整数の生成や、くじ引き・シャッフル処理など、さまざまな場面で乱数を利用できます。Math.random()で1〜10のランダムな整数を生成する方法1から10までのランダムな整数を取得するには、Math.random()の結果に10を掛け、Math.floor()で小数点以下を切り捨てた後、1を加算します。数式で表すと以下のようになります。Math.
-
JavaScriptのPromise(プロミス)とは?非同期処理の基本と使い方を解説
JavaScriptのPromise(プロミス)は、作成された時点ではまだ値が確定していない非同期処理を扱うためのオブジェクトです。APIリクエストやファイルの読み込みなど、完了まで時間がかかる処理について、「いずれ結果を受け取る」という約束を表現します。Promiseは、以下の3つの状態を持ちます。pending(保留中):処理がまだ完了しておらず、成功も失敗も確定していない初期状態fulfilled(履行済み):処理が正常に完了し、結果の値が利用できる状態rejected(拒否済み):処理が失敗し、エラーの理由が利用できる状態一度fulfilledまたはrejectedに遷移したPromi