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

JavaScriptでハーシャッド数を判定し、連続する数列の長さを求める方法

ハーシャッド数とは?

ハーシャッド数とは、その数の各桁の合計値で割り切れる数のことです。例えば126は、1+2+6=9 という各桁の合計で完全に割り切れるため、ハーシャッド数に該当します。

  • すべての1桁の数(1〜9)はハーシャッド数です。
  • ハーシャッド数は、[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] や [110, 111, 112]、[1010, 1011, 1012] のように、連続したまとまり(クラスター)として存在することがよくあります。

今回の課題は、数値を入力として受け取り、それがハーシャッド数かどうかを判定する関数を作成することです。ハーシャッド数でない場合は -1 を返し、ハーシャッド数である場合は、その数を含む連続したハーシャッド数の並び(ストリーク)の長さを返します。

具体例を見てみましょう。

harshadNum(1014) = harshadNum(1015) = harshadNum(1016) = harshadNum(1017) = 4
harshadNum(1) = 10
harshadNum(12) = 1
harshadNum(23) = -1

問題を2つの関数に分割する

この問題は、次の2つの主要な関数に分けて考えると分かりやすくなります。

  • isHarshad():数値 num を受け取り、それがハーシャッド数かどうかに応じて真偽値を返す補助関数。
  • harshadNum():実際の数値を受け取るメイン関数で、必要な箇所で isHarshad() を呼び出しながらストリークの長さを算出して返します。

isHarshad() 関数の実装

const isHarshad = (num) => {
    let sum = 0, temp = num;
    while(temp){
        sum += temp % 10;
        temp = Math.floor(temp/10);
    }
    return num % sum === 0;
}

各桁の合計を順番に足し合わせていき、最後に元の数との剰余をチェックするだけの、非常にシンプルな反復処理の関数です。

harshadNum() 関数の実装

続いて、メインとなる harshadNum() 関数のコードです。

const harshadNum = (number) => {
    // 入力がハーシャッド数でない場合は -1 を返す
    if(!isHarshad(number)){
        return -1;
    }
    let streak = 1, prev = number-1, next = number+1;
    // 前の方向へ連続するストリークを確認
    while(isHarshad(prev) && prev > 0){
        streak++;
        prev--;
    }
    // 後ろの方向へ連続するストリークを確認
    while(isHarshad(next)){
        streak++;
        next++;
    }
    return streak;
};
console.log(harshadNum(1014));

コードの解説

  • まず入力値がハーシャッド数かどうかをチェックし、そうでなければその時点で -1 を返して処理を終了します。
  • ハーシャッド数が続く限り、前方向と後ろ方向それぞれに対してループを実行し、カウンタ変数 streak を更新していきます。
  • 最終的な streak の値を結果として返します。

以下が完全なコード全体です。

実行例

const isHarshad = (num) => {
    let sum = 0, temp = num;
    while(temp){
        sum += temp % 10;
        temp = Math.floor(temp/10);
    }
    return num % sum === 0;
}
const harshadNum = (number) => {
    // 入力がハーシャッド数でない場合は -1 を返す
    if(!isHarshad(number)){
        return -1;
    }
    let streak = 1, prev = number-1, next = number+1;
    // 前の方向へ連続するストリークを確認
    while(isHarshad(prev) && prev > 0){
        streak++;
        prev--;
    }
    // 後ろの方向へ連続するストリークを確認
    while(isHarshad(next)){
        streak++;
        next++;
    }
    return streak;
};
console.log(harshadNum(1014));

出力

このコードをコンソールで実行すると、次の出力が得られます。

4
  1. 【JavaScript入門】配列内で最初の非連続な数値を見つける方法

    はじめに本記事では、JavaScriptを使って「数値の配列の中から、直前の要素と連続していない最初の数値」を見つける方法を解説します。アルゴリズムの練習やコーディング面接の対策としても役立つ基本的な問題です。 問題の定義数値の配列を受け取るJavaScript関数を作成する必要があります。この関数は、直前の要素に対して +1 となっていない(連続していない)最初の要素を返さなければなりません。 言い換えると、隣り合う要素同士の差が1以外になる箇所が現れたとき、その箇所の後ろ側の要素を返すという処理です。なお、そのような要素が必ず配列内に1つ以上存在するものとします。 サンプルコード以下は、実

  2. JavaScriptで昇順配列の中から並び順を壊している唯一の要素を見つける方法

    この記事では、昇順(増加順)にソートされた数値の配列の中に、ただひとつだけ並び順を乱している要素がある場合に、その要素を特定して返すJavaScript関数の実装方法を解説します。 問題の定義 扱う配列は基本的に昇順でソートされていますが、その中の要素がひとつだけ順序から外れています。関数の目的は、その「異常な要素」を見つけ出して返すことです。 たとえば、次のような配列を考えます。 const arr = [1, 2, 3, 4, 17, 5, 6, 7, 8]; この配列から「17」を取り除けば残りは完全な昇順になるため、求める答えは「17」です。 解決のアプローチ 昇順の配列では、隣り合う