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

JavaScriptでカタツムリトレイル問題を解く:正方行列を螺旋状に走査する方法

次のような配列があるとしましょう。

const arr = [
    [1, 2, 3, 4],
    [12,13,14,5],
    [11,16,15,6],
    [10,9, 8, 7]
];

この配列は必ず正方行列(行数と列数が等しい行列)になるとします。

問題の概要

求められているのは、この配列を受け取り、要素を外側から内側へと渦巻き状にたどりながら、中心へ収束するように新しい配列を構築するJavaScript関数です。

イメージとしては、行列の外周をカタツムリが這うように、ぐるりと一周しては少しずつ内側へ進んでいく形になります。これが「カタツムリトレイル(Snail Trail)」問題と呼ばれる理由です。

したがって、上記の配列に対する期待される出力は次のとおりです。

const output = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];

左上の 1 から始まり、右へ進んで 4 まで行き、下へ折れて 7 まで、さらに左へ 10 まで、そして上へ戻りながら徐々に中心へ向かう——まさに螺旋状の走査になっていますね。

解決アプローチ:再帰を使う

それでは、この関数のコードを書いてみましょう。ここでは再帰処理を使ってこの問題を解いていきます。

基本的な考え方はシンプルで、次の手順を繰り返すだけです。

  • まず行列の一番上の行を取り出して結果に連結する
  • 残りの行列を反時計回りに90度回転させる
  • これを再帰的に繰り返し、最後の1行だけになったらそれを返す

コード例

実装は次のようになります。

const arr = [
    [1, 2, 3, 4],
    [12,13,14,5],
    [11,16,15,6],
    [10,9, 8, 7]
];
const spiralForm = arr => {
    return arr.length > 1 ?
    arr.splice(0,1)[0]
    .concat(spiralForm(arr[0].map((c, i) => {
        return arr.map(r => r[i]);
    })
    .reverse())) :
    arr[0]
}
console.log(spiralForm(arr));

コードの仕組み

このコードがどのように動作しているのか、順を追って見ていきましょう。

  1. arr.splice(0,1)[0] — 元の配列から先頭の行を取り除き、その行を返します。これが螺旋の最初の一辺に相当します。
  2. arr.map(r => r[i]) — 残りの行列から i 番目の列を抽出します。これにより行列を「縦読み」できます。
  3. .reverse() — 抽出した列を逆順に並べ替えることで、残りの行列を反時計回りに90度回転させた状態を作ります。
  4. 回転させた行列に対して同じ処理を再帰的に適用し続け、要素が1行だけになった時点で arr[0] を返して終了します。

つまり「上の行を取る → 残りを回転させる」という操作を繰り返すことで、あたかもカタツムリが外側から内側へ這っているかのような順序で、すべての要素を一括して取得できるのです。

実行結果

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

[
    1, 2, 3, 4, 5, 6,
    7, 8, 9, 10, 11, 12,
    13, 14, 15, 16
]

期待どおり、元の行列が螺旋状に展開された一次元配列が得られました。

まとめ

カタツムリトレイル問題は、二次元配列の操作と再帰の考え方を同時に学べる、とても良い練習問題です。ポイントは「先頭行の取り出し」と「行列の90度回転」を組み合わせて、問題を毎回小さくしていくこと。ぜひご自身でも別サイズの行列で試してみてください。

  1. JavaScriptで配列を空にする方法まとめ【3つの手法と使い分けのポイント】

    JavaScriptで配列を空にする(初期化する)方法は複数あります。それぞれの手法には特徴や注意点があり、状況に応じて適切に使い分けることが重要です。この記事では、代表的な3つの方法と、それぞれのメリット・デメリットを詳しく解説します。まず、以下のような配列があると仮定します。let arr = [1, test, {}, 123.43];方法1:新しい空の配列で置き換えるarr = [];変数arrに新しい空の配列を再代入する方法です。最もシンプルかつ高速な手法として知られています。ただし注意点として、元の配列への参照がプログラムの他の場所に存在する場合、それらの参照は自動的に更新されませ

  2. JavaScriptの基本配列メソッド解説!push・pop・shift・unshift・spliceの使い方を実例付きで紹介

    JavaScriptには、配列を操作するための便利な組み込みメソッドが数多く用意されています。その中でも特によく使われるのが、要素の追加や削除を行う以下の5つの基本メソッドです。 JavaScriptの主要な配列メソッド一覧 メソッド説明 Array.push()配列の末尾に要素を追加します。 Array.pop()配列の末尾から要素を取り除きます。 Array.unshift()配列の先頭に要素を追加します。 Array.shift()配列の先頭から要素を取り除きます。 Array.splice()配列内の任意の位置で要素の追加・削除を行います。 これらのメソッドは、配列の