JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptで残りの数の合計が2つの数の積に等しくなるペアを見つける方法

問題の概要

1から任意の整数 num までの連続した数列を考えます。この中から2つの数(それぞれ mn と呼びます)を選び、次の条件を満たす組み合わせを見つけます。

sum(1 to num) - (m + n) = m * n

つまり、「選んだ2つの数を除いた残りの数の合計」が「選んだ2つの数の積」と等しくなるようなペアです。最終的に、条件を満たすすべての組み合わせを配列として返します。

具体例

入力が次の場合を考えてみましょう。

const num = 10;

このときの出力は次のようになります。

const output = [
    [7, 6]
];

理由はシンプルで、1から10までの合計が 55 であり、

55 - (6 + 7) = 6 * 7 = 42

という等式が成立するためです。つまり、6 と 7 を取り除いた残りの数の合計(42)が、6 × 7 の積(42)と一致します。

実装コード

この問題は次のように解くことができます。

const num = 10;
const pickNumbers = num => {
    const sum = (num) * (num + 1) * (.5);
    const results = [];
    for (let n = 1; n <= num; n++) {
        let first = sum - n;
        let second = n + 1;
        if (first % second === 0) {
            let m = first / second;
            if (m < num && m !== n && results.every(group => group[0] + group[1] !== m + n)){
                results.push([m, n]);
            }
        }
    }
    return results;
}
console.log(pickNumbers(10));

コードの解説

このアルゴリズムのポイントは以下の3点です。

  • 合計の高速な計算: 等差数列の和の公式 n(n+1)/2 を利用することで、1から num までの合計をループなし(O(1))で求めています。
  • m を一意に導出する変形: 条件式 sum − (m + n) = m × n を m について解くと、m = (sum − n) / (n + 1) となります。これにより、n を1つ決めれば対応する m がすぐに計算でき、全ペアを総当たりする必要がなくなります。
  • 妥当性チェック: m が整数であること(first % second === 0)、num 未満であること、n と異なること、さらに同じペアの重複登録を防ぐ確認を行ったうえで、結果に追加しています。

実行結果

コンソールには次のように出力されます。

[
    [7, 6]
]

すべてのペアを二重ループで調べる O(num²) のアプローチと比べ、この方法はループが1回で済むため、大きな num に対しても効率的に動作します。数式を事前に変形しておくことで探索範囲を大きく絞れる、数学的な工夫が活きた良い例といえるでしょう。

  1. 【JavaScript】整数の中からn番目の回文数を見つける方法

    問題 数値 n を引数として受け取り、0から数えて n 番目にあたる回文数(回文となる整数)を返す JavaScript 関数を作成します。 たとえば、1番目の回文数は「0」、2番目は「1」、10番目は「9」です。「10」は逆から読むと「01」となり回文ではないため、11番目の回文数は「11」となります。 回文数とは 回文数とは、桁を逆から並べ替えても元の数と同じになる整数のことです。「7」「121」「1331」などがその例です。 解決策:コード例 以下が実際のコードです。 const num = 31; const findNthPalindrome = (num = 1) => {

  2. JavaScriptで増加する三角形のn行目の全数値の合計を求める方法

    増加する三角形とはこの問題における「増加する三角形」とは、次のような形の三角形を指します。    1   2 3  4 5 67 8 9 10ご覧のとおり、各行には連続する自然数が左から右へと順に配置され、行が下に進むほど要素の数が1つずつ増えていきます。問題の概要数値 n を受け取り、増加する三角形の n 行目に含まれるすべての数値の合計を返すJavaScript関数を作成する必要があります。例えば15行目の場合、その行には105から120までの連続する15個の数値が含まれており、それらの合計は1695