【JavaScript】1つの範囲に含まれる複数の範囲の合計を求めるアルゴリズム
問題の概要
ここでは、2種類の範囲(レンジ)を扱います。1つは任意の長さを持つ単一の範囲 R1、もう1つは複数の範囲からなる集合 R2 です。R2 に含まれる各範囲は、R1 に完全に収まることもあれば、一部だけが重なることも、まったく重ならないこともあります。
目的は、R2 の各範囲のうち R1 と重なっている部分(全体または一部)の長さをすべて合計することです。
入力例 1
const R1 = [20,40];
const R2 = [[14,22],[24,27],[31,35],[38,56]];
結果
= 2+3+4+2 = 11
[14,22] は R1=[20,40] との重なりが 20〜22 のため長さは 2。同様に [24,27] は 3、[31,35] は 4、[38,56] は 38〜40 の部分のみ重なり長さ 2 となります。これらを合計すると 11 が答えです。
入力例 2
R1 = [120,356];
R2 = [[234,567]];
結果
122
[234,567] は R1 と 234〜356 の区間でのみ重なるため、その長さ 122 が答えになります。
実装例
それでは、実際のコードを見てみましょう。
const R1 = [20,40];
const R2 = [[14,22],[24,27],[31,35],[38,56]];
const R3 = [120,356];
const R4 = [[234,567]];
function sumRanges(range, values) {
const [start, end] = range;
const res = values.reduce((acc, val) => {
const [left, right] = val;
const ex1 = Math.min(right, end);
const ex2 = Math.max(left, start);
const diff = ex1 - ex2;
return acc + Math.max(0, diff);
}, 0);
return res;
};
console.log(sumRanges(R1, R2));
console.log(sumRanges(R3, R4));
コードの解説
このアルゴリズムのポイントは以下のとおりです。
- まず、基準となる範囲 range を start(始点)と end(終点)に分解します。
reduceを使い、values 内の各範囲 [left, right] を順番に処理していきます。- 重なり区間の右端は
Math.min(right, end)、左端はMath.max(left, start)で求められます。 - 両者の差 diff が正であれば、それが実際の重なり(交差)の長さです。
- diff が負になる場合、つまり範囲がまったく重ならない場合は
Math.max(0, diff)によって 0 として扱われ、合計に影響しません。
出力結果
コンソールには次のように出力されます。
11
122
まとめ
Math.min と Math.max を組み合わせて交差区間を求め、負の値を 0 に丸めることで、複雑な if 文による条件分岐を書かずに「範囲の重なり合計」を簡潔に計算できます。この手法は、予約時間帯の重複集計やデータ区間のフィルタリングなど、さまざまな場面で応用できる汎用的なパターンなので、ぜひ覚えておきましょう。
-
JavaScriptで範囲内の「1に収束する素数」を数える方法
問題概要 2つの数値からなる範囲配列を受け取るJavaScript関数を作成します。この関数は、範囲内にある素数のうち、各桁の数字の2乗の和を繰り返し計算すると最終的に1に到達する数の個数を返します。 たとえば23は素数であり、次のように計算が進みます。 22 + 32 = 13 12 + 32 = 10 12 + 02 = 1 最終的に1になったため、23は条件を満たす有効な数です。なお、この性質を持つ数は一般に「ハッピー数」と呼ばれ、素数であるハッピー数は「ハッピー素数」として知られています。 コード例 以下が実際のコードです − const range = [2, 212]; Strin
-
JavaScriptで3つの配列に共通する要素の合計を求める方法
問題今回は、3つの数値型配列を引数として受け取るJavaScript関数を作成します。この関数は、3つの配列すべてに共通して存在する要素だけを抜き出し、それらの合計値を返す必要があります。たとえば、次のような配列が与えられた場合を考えてみましょう。const arr1 = [4, 4, 5, 8, 3]; const arr2 = [7, 3, 7, 4, 1]; const arr3 = [11, 0, 7, 3, 4];この場合、3つの配列すべてに存在するのは「4」と「3」なので、期待される出力は 4 + 3 = 7 となります。解決策のコード例以下がその実装コードです。 { le