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

JavaScriptで「美しい配置」を数える:バックトラッキングによる効率的な解法

美しい配置(Beautiful Arrangement)とは?

1からnumまでのnum個の整数があるとします。これらの整数を使って構成される配列が「美しい配置」であるためには、配列のi番目の位置(1 ≦ i ≦ N)について、次のいずれかの条件が満たされている必要があります。

  • i番目の位置にある数値が、iで割り切れる。

  • iが、i番目の位置にある数値で割り切れる。

問題

数値numを受け取り、そのnumに対して構築できる「美しい配置」の総数を返すJavaScript関数を作成してください。

例えば、関数への入力が次の場合:

const input = 2;

期待される出力は次のとおりです。

const output = 2;

出力の説明

1つ目の美しい配置は [1, 2] です。

2つ目の美しい配置は [2, 1] です。

実装コード

const num = 4;
const countArrangements = (num = 1) => {
   let ans = 0
   const recur = (curr, vis) => {
      if (curr === 1){
         ans++;
      }else{
         for (let i = num; i; i--) {
            let possible = (i % curr === 0 || curr % i === 0);
            let visited = vis & 1 << i;
            if (possible && !visited){
               recur(curr-1, vis | 1 << i);
            }
         }
      }
   };
   recur(num, 0);
   return ans;
};
console.log(countArrangements(num));

コードの解説

まず、結果を格納する変数(ans)を定義し、分岐する可能性をすべて探索するための再帰関数を作成します。この再帰関数が必要とする引数は2つだけです。現在配置しようとしている数値(curr)と、すでに使用済みの数値を記録するフラグ(vis)です。

ここでのポイントは、visをビットマスクとして扱っている点です。各ビットが対応する数値の使用状況を表すことで、メモリを節約しながら高速に状態管理ができます。また、条件式 i % curr === 0 || curr % i === 0 によって、その数値が現在の位置と割り切れる関係(約数・倍数の関係)にあるかどうかを判定し、条件を満たさない組み合わせは早期に枝刈りすることで、探索範囲を大幅に絞り込んでいます。

実行結果

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

8

これは、num = 4 の場合に構築可能な「美しい配置」が全部で8通り存在することを示しています。この手法はバックトラッキングの一種であり、無駄な探索を切り捨てることで、全順列を生成するよりもはるかに効率的に答えを求められます。

  1. JavaScriptの数値(Number)の基本と実践サンプルコード

    JavaScriptでは、整数も小数もすべて「Number」型として扱われます。この記事では、数値変数の定義方法と、それらを使った簡単な演算の例を、動作するHTMLサンプルコードとともに紹介します。サンプルコード以下は、JavaScriptで数値を扱う基本的な例です。整数(22、99)と小数(1.523)を変数に格納し、ボタンをクリックすると画面に表示する仕組みになっています。<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport co

  2. JavaScriptで数値に序数接尾辞(st・nd・rd・th)を追加する方法

    問題JavaScriptで関数を作成する必要があります。この関数は、数値 num を最初の(唯一の)引数として受け取ります。関数の役割は、英語の序数表記のルールに従って、数値に「st」「nd」「rd」「th」という接尾辞を追加することです。具体的なルールは以下の通りです。一の位が1で終わる数値には「st」を使用します(例:1st、発音はfirst)一の位が2で終わる数値には「nd」を使用します(例:92nd、発音はninety-second)一の位が3で終わる数値には「rd」を使用します(例:33rd、発音はthirty-third)上記ルールの例外として、下二桁が11・12・13となる数値に