2進数の末尾に文字列を連結して「次の5の倍数」を求めるJavaScript関数の実装方法
問題
数値 n を引数として受け取り、その数値の2進表現の末尾に最短の2進文字列を連結することで得られる「次に大きい5の倍数」を返すJavaScript関数を作成します。
たとえば入力が 8 の場合、8 の2進表現は 1000 です。ここに最短の2進文字列を順に連結して試し、最初に5の倍数になった時点の数値を答えとして返します。
アプローチのポイント
- 元の数値を2進文字列に変換する
- 長さ1、長さ2…と桁数を増やしながら、ありうるすべての2進パターンを生成する
- 各パターンを末尾に連結し、10進数に戻した値が5で割り切れるかを判定する
- 割り切れた瞬間の値を即座に返す
コード例
const generateAll = (num = 1) => {
const res = [];
let max = parseInt("1".repeat(num), 2);
for(let i = 0; i <= max; i++){
res.push(i.toString(2).padStart(num, '0'));
};
return res;
};
const smallestMultiple = (num = 1) => {
const numBinary = num.toString(2);
let i = 1;
while(true){
const perm = generateAll(i);
const required = perm.find(binary => {
return parseInt(numBinary + binary, 2) % 5 === 0;
});
if(required){
return parseInt(numBinary + required, 2);
};
i++;
};
};
console.log(smallestMultiple(8));出力
35
コードの解説
まず generateAll 関数は、指定された桁数(num)で表現できるすべての2進文字列を生成する補助関数です。"1".repeat(num) で最大値となる2進数(例:桁数2なら 11)を作り、0からその値までをループしながら padStart を使って先頭を0埋めしています。
本体の smallestMultiple 関数では、対象の数値を2進文字列化したうえで、連結する文字列の長さを1から順に増やしていきます。各長さで生成した全パターンを末尾に連結し、10進数へ変換した結果が5で割り切れるかどうかを find メソッドで判定します。条件を満たすパターンが見つかれば、その値を直ちに返します。
入力 8(2進数:1000)の場合を確認してみましょう。長さ1の候補「0」「1」では 10000(16)、10001(17) となり5の倍数にはなりません。続く長さ2の候補の中で「11」を連結すると 100011(35) となり、これが5の倍数です。したがって出力は 35 となります。
-
JavaScriptのconst宣言とは?再代入できない変数の基本と使い方を解説
JavaScriptのconst宣言は、値を再代入することも後から再宣言することもできない変数を作成するための構文です。constはES2015(ES6)で導入されました。 const宣言の主な特徴 一度値を代入すると、別の値に再代入することはできません。 同じ名前の変数を同じスコープ内で再宣言するとエラーになります。 宣言時に必ず初期値を代入する必要があります。 ブロックスコープ({}内でのみ有効)を持ちます。 それでは、JavaScriptにおけるconst宣言の実際のコードを見ていきましょう。 サンプルコード <!DOCTYPE html> <html>
-
JavaScriptのconstとletの違いを徹底解説!ブロックスコープ変数の基本と使い方
JavaScriptにおけるconstとletの基本const と let は、ES2015(ES6)で導入された変数宣言用のキーワードです。どちらもブロックスコープ(波括弧 { } で囲まれた範囲)に対応しているのが特徴で、関数スコープしか持たなかった従来の var とは異なる挙動を示します。両者の大きな違いは再代入の可否です。letで宣言した変数は後から何度でも値を再代入できますが、constで宣言した変数は再代入しようとするとエラー(TypeError)が発生します。letとconstの主な違い項目letconst再代入可能不可(エラー発生)スコープブロックスコープブロックスコープ宣言時