-
【JavaScript】部分配列の合計として表せない最小の正の整数を求めるアルゴリズム
問題の概要まず、正の整数が昇順にソートされた配列を考えてみましょう。const arr = [1, 3, 6, 10, 11, 15];このような配列を引数として受け取り、「元の配列の部分配列(要素の集まり)の合計として表すことができない最小の正の整数」を返す関数 findSmallest() を作成します。例えば、上記の配列の場合、どの部分配列を足し合わせても到達できない最小の正の整数は「2」です。それでは、この関数のコードを書いていきましょう。アルゴリズムの考え方配列があらかじめソートされているため、この問題は線形時間 O(n) で解くことができます。手順は以下の通りです。最初に、答えとな
-
【JavaScript】2つの配列を比較して共通する要素の数を数え、一致率を求める方法
ここに2つの配列があるとします。1つはある試験の正解を格納した配列、もう1つは受験者が記入した解答を格納した配列です。ただし、何らかの理由で配列の順序がシャッフルされてしまい、対応する順番には並んでいません。ただし、異なる問題が同じ答えを持つことはないものと保証されています。 そこで私たちの課題は、この2つの配列を受け取って互いに共通する要素をすべて検出し、一致した解答の数に基づいて受験者の得点率を計算する関数を作成することです。 実装例 const correct = [India, Japan, 56, Mount Everest, Nile, Neil Armstrong, Incept
-
JavaScriptで数値nを受け取り、最初のn個の素数を配列として生成する関数の実装方法
本記事では、数値 n を受け取り、最初の n 個の素数を格納した配列を返す JavaScript 関数の作成方法を解説します。素数とは、1 とその数自身でしか割り切れない数のことで、2、3、19、37、73 などが代表的な例です。 実装の手順としては、まず与えられた数が素数かどうかを判定する関数を用意し、その後ループ処理によって n 個の素数を順番に生成していきます。まずは素数を判定するコードから見ていきましょう。 素数を判定する関数 const isPrime = (n) => { for(let i = 2; i <= n/2; i++){  
-
JavaScriptで数値がフィボナッチ数かどうかを判定する方法
本記事では、引数として受け取った数値がフィボナッチ数列に含まれるかどうかを判定し、その結果を真偽値(true / false)で返すJavaScript関数の実装方法を解説します。 期待する動作 まず、どのような動作を目指すのか確認しましょう。例えば、次のように関数を呼び出した場合: fibonacci(12); fibonacci(89); fibonacci(55); fibonacci(534); 出力は以下のようになります: false true true false このように、12と534はフィボナッチ数列に含まれないため「false」、55と89は含まれるため「true」が返され
-
JavaScriptで再帰を使って配列の合計を求める方法|余分な変数なしで実装するテクニック
はじめに今回は、「数値の配列の全要素を合計する再帰関数」を書くことを考えます。ただし、ここにはひとつの条件があります。その再帰関数では、余分な変数(メモリ)を一切初期化してはいけないというものです。つまり、合計値を保存するための変数や、配列のインデックスをカウントするための変数などは使えません。すべて、すでに手元にあるものだけで実装する必要があります。一見すると制約が厳しく感じますが、実はとてもシンプルな発想で解決できます。以下、その解法を紹介します。アプローチのポイント鍵となるのは、「すでに持っている配列そのもの」を活用することです。具体的には、配列の最初の要素(0番目の要素)を、再帰的な合
-
【JavaScript】配列の各サブ配列の合計を計算して新しい配列を返す方法
問題の概要数値の集合を含む複数の配列(ネストされた配列)が与えられたとき、対応する各サブ配列内のすべての数値の合計を要素とする配列を返す関数を作成します。例たとえば、入力配列が次のようになっているとします。const numbers = [ [1, 2, 3, 4], [5, 6, 7], [8, 9, 10, 11, 12] ];この場合、関数の出力は次のようになるはずです。const output = [10, 18, 50];実装方法この問題は、Array.prototype.reduce() メソッドを組み合わせることで簡潔に解決できます。まず、1つの配列の合計
-
JavaScriptのwhileループで連続する数値の最長部分配列を見つける方法
はじめに本記事では、正の整数の配列の中から「連続した数値が続く最長の部分配列」の長さを求める関数を、while文を使って実装する方法を解説します。例えば、入力配列が以下の場合を考えてみましょう。const input = [6, 7, 8, 6, 12, 1, 2, 3, 4]; // 最長の連続部分配列は [1,2,3,4]この場合、出力は次のようになります。4また、別の入力配列の例です。const input = [5, 6, 1, 8, 9, 7]; // 最長の連続部分配列は [8,9]この場合の出力は次のとおりです。2それでは、この関数の実装コードを見ていきましょう。実装コード {
-
JavaScriptで次のn個のうるう年を取得する方法
本記事では、正の整数 n を受け取り、次の n 個のうるう年を配列として返す関数を作成します。この問題は、以下の3つのパートに分けて考えると分かりやすくなります。パート1:JavaScriptで現在の年を取得するまず、Date オブジェクトの新しいインスタンスから現在の年を取得します。コードは次のとおりです。// Dateオブジェクトのインスタンスから現在の年を取得 const year = new Date().getFullYear();パート2:うるう年の判定次に、数値を受け取り、その年がうるう年かどうかを真偽値(boolean)で返す関数 isLeap() を作成します。ある年がうるう
-
JavaScriptで2つの配列を逆順に対応させながら合計する方法
本記事では、2つの数値配列(例えば first と second)を受け取り、新しい配列を返す関数 reverseSum() を実装する方法を解説します。返される配列には、以下のような要素が含まれます。 1つ目の配列の先頭要素と、2つ目の配列の末尾要素の合計が、新しい配列の最初の要素になる 1つ目の配列の2番目の要素と、2つ目の配列の後ろから2番目の要素の合計が、次の要素になる(以降も同様) どちらか一方の配列の要素が先に尽きた場合は、残りの要素をそのまま新しい配列の末尾へ追加します。それでは、この関数のコードを見ていきましょう。 コード例 const first = [23, 5, 7
-
【JavaScript】再帰関数を使ってネストされた配列内のfalsy値(NaN・undefined・null)を0に置き換える方法
ネストされた配列のfalsy値を一括で置き換えたい JavaScriptでは、配列の中に配列が含まれる「ネストされた(多次元)配列」を扱うことがあります。たとえば、次のようなデータ構造です。 const arr = [3, 5, 7, 2, [4, NaN, null, 4, 8, [3, undefined, 24, null], null, 5, 1], NaN, 45, 2, 1]; このような配列には、NaN、undefined、nullといったfalsy値(偽と評価される値)が含まれていることがあります。 今回の課題は、再帰関数(recursive function)を作成し、ネスト
-
JavaScriptで最も近い回文数を求める関数を実装する方法
概要 本記事では、数値 n を受け取り、その数値に最も近い回文数(左から読んでも右から読んでも同じ値になる数)を返す関数 nearestPalindrome() の実装方法を解説します。 期待される動作は次の通りです。 入力が 264 の場合 → 出力は 262 入力が 7834 の場合 → 出力は 7887 アプローチの基本アイデア 考え方はシンプルです。対象の数値を文字列として扱い、桁数を基準に前半と後半に分割します。そのうえで、後半部分を「前半部分の鏡像(逆順に並べたもの)」で置き換えて連結すれば、元の数値に非常に近い回文数を効率よく生成できます。 具体的な手順は以下の通りです。
-
JavaScriptで配列の末尾のn個の要素を先頭に移動する方法
配列に対して使える関数 prependN() を作ることを考えてみましょう。この関数は数値 n(関数を適用する配列の長さ以下である必要があります)を受け取り、配列の末尾から n 個の要素を取り出して、それらを配列の先頭へ移動させます。 重要なのは、この処理を「その場で(in-place)」行うこと、そして関数は処理の成否を表すブール値だけを返すという点です。 たとえば、次のようなケースを考えてみます。 // 入力配列が以下の場合: const arr = [blue, red, green, orange, yellow, magenta, cyan]; // 数値 n が 3 のとき、 //
-
【JavaScript】文字列内で連続して繰り返される文字の最大数を取得する方法
問題の概要以下のように、同じ文字が繰り返し含まれる文字列があるとします。const a = fdsfjngjkdsfhhhhhhhhhhhfsdfsd;私たちの課題は、同じ文字が連続して出現する最大回数(ストリークの長さ)を返す関数を実装することです。上記の文字列では、文字「h」が11回連続して出現しているため、この文字列を渡した場合の関数の戻り値は11となります。アプローチ:スライディングウィンドウアルゴリズムこの種の問題は、スライディングウィンドウ(滑動窓)アルゴリズムが非常に有効です。ここでいう「安定したウィンドウ」とは、同じ文字のみが連続して含まれている区間のことを指し、異なる文字が混
-
JavaScriptでソートを使わずに配列から2番目に小さい値を取得する方法
数値の配列が与えられたとき、その配列から2番目に小さい値を返す関数を作成する必要があります。ポイントは、sort()メソッドなどで配列を並べ替えることなく実装することです。例として、次のような配列を考えてみましょう。const arr = [67, 87, 56, 8, 56, 78, 54, 67, 98, 56, 54];この場合、期待される出力は次のとおりです。54これは、配列内の最小値が 8 であり、それより大きい値の中で最も小さいのが 54 だからです。重複する値(56 や 54)が存在することにも注目してください。実装例:Math.min() と indexOf() を活用する方法
-
JavaScriptで配列の合計を求める:再帰・forループ・ES6メソッドのパフォーマンス比較
膨大な数の数値エントリを含む配列があるとします。ここで、配列内の全要素を合計する処理について、「再帰」「単純なforループ」「ES6関数」の3つのアプローチがそれぞれどれほどの時間を要するのかを比較してみましょう。すなわち、再帰 vs forループ vs ES6関数の性能対決です。 ここでは巨大な配列そのものを用意する代わりに、比較的小さな配列に対して大量の反復処理(約1億回)を実行することで計測をシミュレートします。主眼はあくまで、各手法が配列の合計に要する時間のおおよその比率を把握することにあります。 手法1:再帰によるアプローチ const recursiveSum = (arr, le
-
JavaScriptで配列内の最頻出要素(最も多く出現するアイテム)を取得する方法
JavaScriptでは、数値や文字列などのリテラル値を含む配列を扱うことがあります。その中には同じ値が何度も繰り返し登場することもあるでしょう。 本記事では、配列内で最も多く出現する要素を返す関数の作成方法を解説します。 問題の概要 たとえば、次のような入力配列があったとします。 const input = [a, v, k, f, a, f, s, d, d, f, a, j, a]; この場合、期待される出力は次のとおりです。 a 理由は単純で、文字 a が他のどの要素よりも多く出現しているからです。 実装のアプローチ この問題を解決するために、Map() オブジェクトを使用して「各要素
-
JavaScriptで2つのオブジェクトを比較し、類似度(0〜100%)を返す方法
JavaScriptでは、2つのオブジェクトがどれくらい似ているかを数値で評価したいケースがあります。本記事では、オブジェクト同士を比較して、類似度を0〜100の数値(パーセンテージ)として返す関数を実装する方法を解説します。前提となるサンプルデータ例として、次のような2つのオブジェクトを用意します。const a = { Make: Apple, Model: iPad, hasScreen: yes, Review: Great product!, }; const b = { Make: Apple, Model: iPad, wa
-
JavaScriptでシャーロック配列の問題を解く方法|左右の合計が等しい要素を見つける
ワトソンはシャーロックに長さNの配列Aを渡します。そして、「その配列の中に、ある要素を基準としたとき左側の要素の合計と右側の要素の合計が等しくなるような要素が存在するかどうか」を判定するよう求めます。 今回はこの問題をJavaScriptの関数として実装します。関数は数値の配列を受け取り、条件を満たす要素が存在すればそのインデックスを返し、存在しない場合は-1を返します。 アルゴリズムの考え方 この問題を効率よく解くカギとなるのは、配列全体の合計値を先に計算しておくことです。あとは配列を先頭から順に走査しながら、次の手順を繰り返します。 合計値から現在の要素を引く → 残った値が右側の合計に
-
JavaScriptで文字列を連結せずに数値計算を実行する方法【単項プラス演算子】
たとえば、数値を表す文字列からなる次のような配列があるとします。const arr = [3, 3, 55, 23, 67, 43, 12, 67, 87, 12];このような配列を受け取り、各要素を文字列として連結するのではなく、すべての要素を数値として合計した値を返すJavaScript関数を作成する必要があります。解決策:単項プラス(+)演算子を使うこの問題は、単項プラス演算子(+)を使うことでシンプルに解決できます。実際に関数のコードを書いてみましょう。コード例const arr = [3, 3, 55, 23, 67, 43, 12, 67, 87, 12]; const sumSt
-
JavaScriptで配列の指定位置からn個の数値を取得する関数を実装する方法
本記事では、3つの引数を受け取る配列関数 Array.prototype.get() を実装していきます。第1引数は取得する要素数を表す数値 n、第2引数は開始位置を表す数値 m(m は配列の長さ − 1 以下である必要があります)、第3引数は「left」または「right」のいずれかの値を持つ文字列です。 この関数は、元の配列のうち、インデックス m を起点として指定された方向(left なら左、right なら右)に向かって n 個の要素を含む部分配列を返します。重要なのは、配列の端に達したら反対側の端へ折り返す(循環する)という仕様です。 期待される動作 たとえば、次のようなケースを考え