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

JavaScriptで「良い基数(Good Base)」の最小値を求めるアルゴリズム

良い基数(Good Base)とは

整数 num に対して、num を基数 k で表したときに、そのすべての桁が 1 になるような k(k >= 2)のことを「良い基数(Good Base)」と呼びます。

例えば、13 を基数 3 で表すと 111 となるため、3 は num = 13 における良い基数です。

問題の概要

数値を表す文字列 str を唯一の引数として受け取り、str の良い基数となる最小の数値を文字列形式で返す JavaScript 関数を作成する必要があります。

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

const str = "4681";

出力は次のようになります。

const output = "8";

出力の説明

これは、4681 を基数 8 で表すと 11111 になるためです。

実装のポイント

この問題では、数値が非常に大きくなる可能性があるため、JavaScript の BigInt を使用して正確な演算を行います。また、桁数ごとに「すべての桁が 1 になる基数」が存在するかを 二分探索 で効率的に調べることで、計算量を抑えています。桁数が多いほど基数は小さくなるため、桁数の大きい方から順に探索することで、最初に見つかった基数が最小の良い基数となります。どの桁数でも見つからない場合は、num - 1(基数 10 で「11」と表される)が必ず答えになります。

コード例

この実装は以下のようになります。

const str = "4681";
const smallestGoodBase = (n = '1') => {
   const N = BigInt(n), bigint2 = BigInt(2), bigint1 = BigInt(1), bigint0 = BigInt(0)
   let maxLen = countLength(N, bigint2) // result at most maxLen 1s
   const findInHalf = (length, smaller = bigint2, bigger = N) => {
      if (smaller > bigger){
         return [false];
      };
      if (smaller == bigger) {
         return [valueOf1s(smaller, length) == N, smaller]
      };
      let mid = (smaller + bigger) / bigint2;
      let val = valueOf1s(mid, length);
      if(val == N){
         return [true, mid];
      };
      if (val > N){
         return findInHalf(length, smaller, mid - bigint1);
      };
      return findInHalf(length, mid + bigint1, bigger);
   };
   for (let length = maxLen; length > 0; length--) {
      let [found, base] = findInHalf(length);
      if(found){
         return '' + base;
      }
   };
   return '' + (N - 1);
   function valueOf1s(base, lengthOf1s) {
      let t = bigint1
      for (let i = 1; i < lengthOf1s; i++) {
         t *= base
         t += bigint1
      }
      return t
   }
   function countLength(N, base) {
      let t = N, len = 0
      while (t > bigint0) {
         t /= base
         len++
      }
      return len
   }
};
console.log(smallestGoodBase(str));

出力結果

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

8
  1. JavaScriptで配列に存在しない最小の正の整数を見つける方法

    JavaScriptでは、整数の配列を第一引数(唯一の引数)として受け取る関数を作成する必要があります。この関数の役割は、配列に存在しない最小の正の整数を見つけて返すことです。問題の例たとえば、入力配列が次のような場合を考えてみましょう。const arr = [4, 2, -1, 0, 3, 9, 1, -5];このとき、期待される出力は次のとおりです。const output = 5;理由は簡単です。1、2、3、4はすでに配列内に存在していますが、5は配列に含まれていないため、存在しない最小の正の整数となります。なお、負の数(-1、-5)や0は正の整数ではないため、答えの候補からは除外され

  2. Pythonで最小の「良い基数(グッドベース)」を二分探索で求める方法

    問題の概要 整数 n が与えられたとき、n を k 進法で表した際にすべての桁が 1 になるような k(k ≥ 2)を「良い基数(グッドベース)」と呼びます。数値 n が文字列として与えられるので、最小の良い基数を文字列として返します。 例えば n = 121 の場合、答えは 3 です。121 を 3 進法で表すと 11111 となり、すべての桁が 1 になるためです(実際に 1 + 3 + 9 + 27 + 81 = 121 が成り立ちます)。 解法のアプローチ この問題は二分探索を用いることで効率的に解けます。考え方のポイントは次の通りです。 基数 k・桁長 length のときの「