JavaScriptを使ってn回の操作後に開いている水道の蛇口の数を求める方法
問題
ある学校の創立記念日の行事で、次のようなゲームが行われたとします−
「n」個の水道の蛇口があり、「n」人の生徒が無作為に選ばれます。先生は最初の生徒に、すべての蛇口へ行って開けるよう指示します。続いて2番目の生徒には、2番目ごとの蛇口を閉めさせます。3番目の生徒は、3番目ごとの蛇口に対して、閉まっていれば開け、開いていれば閉めます。4番目の生徒も同様に、4番目ごとの蛇口に対して同じ操作を行います。この操作をn番目の生徒まで終えたとき、何個の蛇口が開いていることになるでしょうか。
ここで求められているのは、数値 n を受け取り、開いている蛇口の数を返す JavaScript 関数を作成することです。
考え方
i 番目の蛇口が開けられたり閉められたりする回数は、i の約数の個数と一致します。たいていの数は約数が偶数個あるため、最終的には閉じた状態に戻ります。ところが完全平方数だけは例外で、約数が奇数個(例:9 の約数は 1・3・9 の3つ)存在するため、奇数回の操作を経ても最後まで開いたままになります。
したがって、開いている蛇口の数は「n 以下の完全平方数の個数」、すなわち ⌊√n⌋ に等しいことが分かります。これにより、全員の操作を実際にシミュレーションしなくても、O(√n) で効率的に答えを求められます。
例
以下がそのコードです−
const num = 15;
const openTaps = (num = 1) => {
const arr = [];
let index = 1;
while(index ** 2 <= num){
arr.push(index++ ** 2);
};
return arr.length;
};
console.log(openTaps(num));出力
3
num = 15 の場合、15 以下の完全平方数は 1・4・9 の3つだけなので、開いたまま残る蛇口は3個となります。コードは n 以下の完全平方数を順に配列へ格納し、その個数を返すことでこの数学的な性質をシンプルに利用しています。
-
JavaScriptで配列内の特定の数値に最も近い2つの要素を検索する方法
問題の概要JavaScriptで、ソート済みの整数配列 arr を第一引数に、目標となる数値 target を第二引数に受け取る関数を作成します。この関数は、配列内に存在する要素の中から target に最も近い2つの数値を選び、それらを昇順に並べた配列として返す必要があります。例えば、以下のような入力が与えられた場合を考えてみましょう。入力:const arr = [1, 2, 3, 4, 5];const target = 3;出力:const output = [2, 3];この場合、target の値が 3 であるため、最も近い2つの要素は 2 と 3 となり、昇順に並べて [2, 3
-
【C++】庭全体に水をやるために開くべき蛇口の最小本数を求める
x軸上に一次元の庭があるとします。庭の始点は位置0、終点は位置nです。庭には位置[0, 1, ..., n]に合計n + 1個の蛇口が設置されています。ここで、整数nと長さn + 1の整数配列rangesが与えられ、ranges[i]は「i番目の蛇口を開けると、範囲[i - ranges[i], i + ranges[i]]へ水をまける」ことを表します。この問題の目的は、庭全体に水を行き渡らせるために開く必要のある蛇口の最小本数を求めることです。どのように組み合わせても全域をカバーできない場合は、-1を返します。たとえば、入力がn = 5、ranges = [3, 4, 1, 1, 1, 0]