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

【JavaScript】配列の全要素を割り切れるn桁の最小の数を求める方法

本記事では、第一引数に整数 n、第二引数に数値の配列を受け取り、「配列のすべての要素で割り切れる n 桁の最小の数」を返す JavaScript 関数の実装方法を解説します。

もし該当する n 桁の数が存在しない場合は、条件を満たす最小の数をそのまま返します。

問題の例

たとえば、次のような配列が与えられたとします。

const arr = [12, 4, 5, 10, 9];

この場合、n = 2 のときも n = 3 のときも、期待される出力は次のとおりです。

180

これは、12・4・5・10・9 のすべてを割り切れる最小の数(最小公倍数)が 180 であり、180 は 2 桁にも 3 桁にも該当するためです。

シンプルな実装例

まずは、最も理解しやすい「総当たり(ブルートフォース)」方式のコードを見てみましょう。

const arr = [12, 4, 5, 10, 9];
const num1 = 2;
const num2 = 3;

// num が配列の全要素で割り切れるかどうかを判定
const allDivides = (arr, num) => arr.every(el => num % el === 0);

// n 桁の最小値から順に探索
const smallestMultiple = (arr, num) => {
    let smallestN = Math.pow(10, num - 1);
    while (!allDivides(arr, smallestN)) {
        smallestN++;
    }
    return smallestN;
};

console.log(smallestMultiple(arr, num1));
console.log(smallestMultiple(arr, num2));

コードの解説

allDivides 関数

Array.prototype.every() メソッドを利用し、引数 num が配列内のすべての要素で割り切れるかどうかを真偽値で返します。

smallestMultiple 関数

n 桁の数のうち最も小さい値 10^(n-1)(例:n = 2 なら 10)を初期値とし、条件を満たす数が見つかるまで 1 ずつ増やしながら探索を行います。

実行結果

180
180

より効率的な方法:GCD と LCM を活用する

総当たり方式はシンプルですが、答えが大きくなるとループの反復回数が膨大になり、パフォーマンスが大きく低下します。

そこで役立つのが数学的なアプローチです。「配列の全要素で割り切れる最小の数」は、配列全体の最小公倍数(LCM)と等しいため、ユークリッドの互除法で最大公約数(GCD)を求めれば、ループ処理なしで瞬時に答えを導き出せます。

// 最大公約数(ユークリッドの互除法)
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));

// 最小公倍数
const lcm = (a, b) => (a * b) / gcd(a, b);

// 配列全体の LCM を求め、n 桁以上の最小の倍数を返す
const smallestMultipleFast = (arr, num) => {
    const base = arr.reduce((acc, el) => lcm(acc, el));
    return Math.ceil(Math.pow(10, num - 1) / base) * base;
};

console.log(smallestMultipleFast([12, 4, 5, 10, 9], 2)); // 180
console.log(smallestMultipleFast([12, 4, 5, 10, 9], 3)); // 180

この方式であれば、配列の要素数や数値の大きさにかかわらず、ほぼ一定の時間で結果を取得できます。実務では、こちらのアプローチを採用することをおすすめします。


  1. 【JavaScript】変換操作を繰り返した後に最小となる合計値を求めるアルゴリズム

    問題 正の整数からなる配列を受け取るJavaScript関数を作成します。配列の各要素には、次の操作を必要な回数だけ繰り返し適用できます。 if (arr[i] > arr[j]) then arr[i] = arr[i] - arr[j] これは「より大きい要素から、別の小さい要素の値を引く」という操作です。これ以上どの要素にも操作を適用できなくなった状態(すべての要素が等しくなった状態)になったとき、関数はその配列の合計値を返す必要があります。 解法のアプローチ この問題の鍵となるのは、引き算を繰り返すと最終的にすべての要素が配列全体の最大公約数(GCD)と等しくなるという数学的な

  2. JavaScriptで括弧文字列のスコアを計算する方法

    問題の概要バランスの取れた角括弧([ と ])のみで構成された文字列 str を引数として受け取り、そのスコアを計算して返すJavaScript関数を作成する必要があります。スコアの計算は、以下のルールに従います。[] のスコアは 12つのバランスの取れた括弧文字列 A と B を連結した AB のスコアは A + Bバランスの取れた括弧文字列 A を囲んだ [A] のスコアは 2 × A入出力例例えば、関数への入力が次の場合:入力const str = [][];出力const output = 2;この場合、[] が2つ並んでいるため、スコアは 1 + 1 = 2 となります。解決アプロー