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

再帰処理を使ったJavaScriptによるハッピー数の判定方法


ハッピー数とは

ハッピー数(Happy Number)とは、各桁の数字を2乗してその和を求めるという操作を繰り返したとき、最終的に1に到達する数のことです。一方、この過程で一度現れた数が再度現れてしまうと、同じサイクルが無限に繰り返されることになり、そのような数は「ハッピー数ではない数」と呼ばれます。

例えば、13はハッピー数です。実際に確認してみましょう。

1^2 + 3^2 = 10
1^2 + 0^2 = 1

このように、13 → 10 → 1 という流れで最終的に1に到達します。一方、36はハッピー数ではありません。

再帰を使った判定関数の実装

ここでは、再帰処理を利用して、ある数がハッピー数かどうかを判定する関数を作成していきます。

この関数の鍵となるのは、すでに出現した数を記録しておくことです。同じ数が2回目に現れた時点で無限ループに陥ることが確定するため、その場合はfalseを返します。逆に、各桁の2乗の和が1になった場合はtrueを返します。

出現済みの数の管理にはオブジェクトを使用します。SetやMapを使うこともできますが、シンプルなオブジェクトでも十分に対応できます。

実際のコードは以下の通りです。

コード例

const squareSumRecursively = (n, res = 0) => {
    if(n){
        return squareSumRecursively(Math.floor(n/10), res+Math.pow((n%10),2));
    };
    return res;
};
const isHappy = (num, map = {}) => {
    if(num !== 1){
        if(map[num]){
            return false;
        }
        map[num] = 1;
        return isHappy(squareSumRecursively(num), map);
    };
    return true;
}
console.log(isHappy(36));
console.log(isHappy(13));
console.log(isHappy(36));
console.log(isHappy(23));

実行結果

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

false
true
false
true

コードの解説

squareSumRecursively 関数は、数値の各桁を再帰的に取り出しながら、それぞれの2乗の和を計算します。n % 10 で最下位の桁を取得し、Math.floor(n / 10) で残りの上位の桁へと処理を進めていく仕組みです。

isHappy 関数は、計算結果が1になるまで再帰的に処理を繰り返します。途中で既に出現した数に到達した場合(map[num] が真になる場合)はfalseを返して処理を打ち切り、無限ループを防止しています。

  1. JavaScriptでNumberオブジェクトを作成する方法をわかりやすく解説

    Numberオブジェクトとは JavaScriptのNumberオブジェクトは、整数や浮動小数点数などの数値データを表すラッパーオブジェクトです。プリミティブな数値に対して各種プロパティやメソッドを利用できるようにする役割を持ちます。 Numberオブジェクトの作成方法 Numberオブジェクトを作成するには、次のような構文を使用します。 var val = new Number(number); ここで重要なポイントがひとつあります。new演算子を付けずにNumber()を呼び出した場合は、オブジェクトを生成するのではなく、引数を数値へ変換する型変換(キャスト)として機能します。たとえ

  2. JavaScriptで小数を検証するには?正規表現を使った実装例を解説

    JavaScriptで小数を検証する方法 JavaScriptで、ユーザーが入力した値が正しい小数(小数点を含む数値)かどうかを判定したい場面はよくあります。そんなときに便利なのが正規表現です。本記事では、match()メソッドと正規表現を組み合わせて、入力値が小数かどうかを検証する方法を、具体的なコード例とともにわかりやすく解説します。 使用する正規表現パターン 今回の検証では、以下の正規表現を使用します。 /^[-+]?[0-9]+\.[0-9]+$/ このパターンの各要素の意味は次のとおりです。 ^[-+]?:文字列の先頭に符号(+ または -)が付いていても、付いていなくてもマッチ