数学で遊ぶ

暗算トリック! デジタルルートで9の倍数を見抜く方法

あなたの誕生日を横に並べて数字を作ってみます。
例えば、1998年2月9日生まれの場合は、19980209とします。

できた数字は「9の倍数」でしょうか?
電卓なしで10秒以内に答えてみてください。
きっと難しいはずです。

しかし、実は簡単にチェックする方法があります。
それは、「各桁の数字を足して1桁になるまで繰り返すこと」です。
計算トリックのタネは、実はとても数学的です。

この不思議な数字の性質を説明する前に、デジタルルートという概念から入っていきましょう!

デジタルルートとは?

デジタルルート(digital root)とは、ある正の整数の各桁の数字を合計し、その合計が一桁になるまで繰り返すことで得られる一桁の数のことです。

ただし、0のデジタルルートは0とします。
負の数のデジタルルートの定義はありませんが、慣例的に絶対値に対して考えることがあります。

9の倍数を見抜く

9の倍数はデジタルルートが9

さて、本題です。
デジタルルートについては次が成り立ちます。

命題
  • デジタルルートが9の数は9の倍数
  • デジタルルートが3,6,9の数は3の倍数

例で見てみましょう!

なぜ9の倍数はデジタルルートが9なのか?

上の命題がなぜ成り立つか見ていきましょう。

まずは(i)から考えます。

双子素数とは何か?──謎に満ちた“2つで1組”の素数たち」で導入した合同式を使って考えていきます。

nを整数とします。
nの各桁の数値をa_k,a_{k-1},\ldots,a_1,a_0とすると、n

n = a_k 10^k + a_{k-1}10^{k-1} + \cdots+a_1 10 + a_0

と書くことができます。

10 \equiv 1 \mod 9

が成り立つので、n

n \equiv a_k + a_{k-1} + \cdots + a_1 + a_0 \mod 9

が成り立ちます。

つまり、「元の数」と「各桁の数の和」は9で割った余りが等しいということが分かります。

デジタルルートは、各桁の数の和を繰り返して1桁にしたものなので上の事実より、nを9で割った余りを表します。

デジタルルートが9の場合、nを9で割った余りは0になります :

n \equiv a_k + a_{k-1} + \cdots + a_1 + a_0 \equiv \cdots \equiv9 \equiv0 \mod 9


つまり、nは9の倍数になるということが分かります。

同様に(ii)を考えます。

10 \equiv 1 \mod 3


より、

n \equiv a_k + a_{k-1} + \cdots + a_1 + a_0 \equiv \cdots \equiv S \mod 3


となります。
(・・・と書いてるところは最初と同じ計算を1桁の数が出てくるまで繰り返しています。)

この時、デジタルルートはSになります。

  • S = 3の時、3 \equiv 0 \mod 3
  • S = 6の時、6 \equiv 0 \mod 3
  • S = 9の時、9 \equiv 0 \mod 3

より

n \equiv 0 \mod 3


となり、nは3の倍数になることが分かります。

9の倍数判定

命題を使って、与えられた数が9の倍数か3の倍数かを判定するプログラムを作成したいと思います。
今回は簡易CLIとして、受け取った引数が3の倍数か9の倍数かを判定します。

Pythonで作ってみよう!

import sys

def digital_root_def(n: int) -> int:
    """
    定義に基づく実装でデジタルルートを求めます。

    各桁の数字を合計し、その結果が 1 桁になるまで繰り返します。

    :param n: 非負の整数
    :return: デジタルルート(0〜9)
    :raises ValueError: n が負の場合
    """
    if n < 0:
        raise ValueError("n は非負整数である必要があります")
    # 1桁ならそのまま返す。10 以上は桁和を繰り返す。
    while n >= 10:
        s = 0
        m = n
        while m:
            s += m % 10 # 最後の桁を加算
            m //= 10 # 最後の桁を削除
        n = s
    return n


def print_digital_root(n: int) -> None:
    """
    n のデジタルルートを計算して出力します。

    :param n: 非負の整数
    """
    try:
        result = digital_root_def(n)
        print(f"{n} のデジタルルートは {result} です。")
    except ValueError as e:
        print(f"エラー: {e}")

def check_nine_multiple(n: int) -> bool:
    """
    n が 9 の倍数かどうかをチェックします。

    デジタルルートが 9 の場合、元の数は 9 の倍数です。

    :param n: 非負の整数
    :return: n が 9 の倍数なら True、そうでなければ False
    :raises ValueError: n が負の場合
    """
    if n < 0:
        raise ValueError("n は非負整数である必要があります")
    return digital_root_def(n) == 9

def check_three_multiple(n: int) -> bool:
    """
    n が 3 の倍数かどうかをチェックします。

    デジタルルートが 3、6、または 9 の場合、元の数は 3 の倍数です。

    :param n: 非負の整数
    :return: n が 3 の倍数なら True、そうでなければ False
    :raises ValueError: n が負の場合
    """
    if n < 0:
        raise ValueError("n は非負整数である必要があります")
    dr = digital_root_def(n)
    return dr == 3 or dr == 6 or dr == 9

if __name__ == "__main__":
    # 最初の引数を整数として受け取りデジタルルートを出力しつつ、9の倍数か3の倍数かを判定
    if len(sys.argv) < 2:
        print("引数がありません。整数を指定してください:\r\npython main.py <整数>")
        sys.exit(1)
    try:
        value = int(sys.argv[1]) # argv[0] はスクリプト名なので argv[1] が最初の引数
        print_digital_root(value)
        if check_nine_multiple(value):
            print(f"{value} は 9 の倍数です。")
        else:
            if check_three_multiple(value):
                print(f"{value} は 3 の倍数ですが、9 の倍数ではありません。")
            else:
                print(f"{value} は 3 の倍数ではありません。")
    except ValueError:
        print("エラー: 整数を指定してください")
        sys.exit(1)
        


ソースコードについて、簡単ですが解説です。
digital_root_def関数がデジタルルートを計算する関数です。
具体的には次のように処理をしています。

外側の while の役割

  • 条件n >= 10(2桁以上のとき)
  • 目的:桁和を計算して、n を1桁に近づける処理(=デジタルルート計算)に入る

内側の while の準備

  • m = n(桁を1つずつ取り出すための作業用変数)
  • s = 0(各桁の合計をためる入れ物)

内側のwhileの役割(桁を1つずつ取り出して足す)

  • 取り出しm % 10 で一番右の桁(1の位)を得る
  • 加算:取り出した桁を s に足す
  • 桁落としm // 10m に代入して、右端の桁を消す
  • 繰り返し条件m が 0 になるまで続ける(=全部の桁を処理するまで)

具体例(m = 123456 のとき)

  • m % 10 = 6s += 6m = 123456 // 10 = 12345
  • m % 10 = 5s += 5m = 12345 // 10 = 1234
  • m % 10 = 4s += 4m = 1234 // 10 = 123
  • m % 10 = 3s += 3m = 123 // 10 = 12
  • m % 10 = 2s += 2m = 12 // 10 = 1
  • m % 10 = 1s += 1m = 0
  • 内側の while を抜けた時点で、s = 1+2+3+4+5+6(元の数の各桁の合計

桁和の反映

  • n = s として、計算した桁和を次の判定対象にする

nが1桁になるまで繰り返す。
n < 10 になったら終了(これがデジタルルート)
もし n >= 10 なら、再び外側の while により同じ手順で桁和を取る

check_nine_multiple関数とcheck_three_multiple関数が命題の内容を実行している関数になります。

JavaScriptで作ってみた!

JavaScriptは埋め込めるので、デジタルルートの計算を体験してください!

デジタルルート計算&倍数判定

デジタルルート計算 と 9/3の倍数判定

※ 先頭のマイナスは無視(絶対値で判定)。空白やカンマは自動で取り除きます。

ここに結果が表示されます。

そのうち、気が向いたらJavaScriptのソースコードも解説します。

まとめ

今回は デジタルルート(桁和を1桁になるまで繰り返す操作)を使い、9の倍数を判定できることを確認しました。

ポイントは 10≡1(mod 9)
元の数と桁和は9で割った余りが等しいため、デジタルルートが9なら9の倍数、3や6なら3の倍数です。
身近な数字でもすぐ試せる実用トリックとして、暗算の検算にも役立ちます。

最後まで呼んで頂き、ありがとうございました。

ABOUT ME
MSK
数学・プログラミング・ゲーム制作が大好きな30代エンジニア。 趣味でUnityやC言語を使って数学を可視化したり、小さなアプリを作ったりしています。 教育・学びの楽しさにも関心があります。