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

Pythonで指定した数値がオーレ数(調和約数)かどうかを判定する方法

ある数 n が与えられたとき、それがオーレ数(Ore number)であるかどうかを判定する方法を解説します。オーレ数とは「約数の調和平均が整数になる数」のことで、「調和約数(harmonic divisor number)」とも呼ばれています。

オーレ数とは?

たとえば入力が 28 の場合を考えてみましょう。28 の約数は次の 6 個あります。

[1, 2, 4, 7, 14, 28]

これらの約数の調和平均は次のように計算できます。

調和平均 = 6 ÷ (1/1 + 1/2 + 1/4 + 1/7 + 1/14 + 1/28) = 6 ÷ 2 = 3

計算結果が整数の 3 になるため、28 はオーレ数であることがわかります。

判定アルゴリズムの手順

オーレ数かどうかの判定は、以下の手順で行えます。

  1. get_all_div():引数 n を受け取り、約数をすべて求める関数を定義します。
  2. 空のリスト div を用意します。
  3. i を 1 から √n の整数部分までループさせます。
  4. n が i で割り切れる場合:
    • 商(n ÷ i)が i と等しい場合(平方数の場合)は、i だけを div に追加します。
    • それ以外の場合は、i と商(n ÷ i)の両方を div に追加します。
  5. get_harmonic_mean():引数 n を受け取り、約数の調和平均を返す関数を定義します。
  6. div = get_all_div(n) で約数リストを取得します。
  7. total を 0、length を div の要素数とし、各約数 d について total に n ÷ d を加算していきます。
  8. total を n で割り、最後に length ÷ total を返します(これが調和平均になります)。
  9. メイン処理では mean = get_harmonic_mean(n) を求め、mean が整数であれば True、そうでなければ False を返します。

実装コード例

def get_all_div(n):
    div = []
    for i in range(1, int(n ** 0.5) + 1):
        if n % i == 0:
            if n // i == i:
                div.append(i)
            else:
                div.append(i)
                div.append(n // i)
    return div

def get_harmonic_mean(n):
    div = get_all_div(n)

    total = 0
    length = len(div)

    for i in range(length):
        total += (n / div[i])

    total /= n
    return length / total

def solve(n):
    mean = get_harmonic_mean(n)
    if mean - int(mean) == 0:
        return True
    return False

n = 28
print(solve(n))

実行結果

入力

28

出力

True

補足:誤差を避けるための工夫

上記のコードでは浮動小数点数を使用しているため、非常に大きな数では丸め誤差が発生する可能性があります。Python 標準ライブラリの fractions.Fraction を使えば、有理数のまま厳密な計算が可能です。

from fractions import Fraction

def is_ore_number(n):
    divs = get_all_div(n)
    s = sum(Fraction(1, d) for d in divs)
    hm = Fraction(len(divs)) / s
    return hm.denominator == 1

まとめ

オーレ数の最初の例としては、1, 6, 28, 140, 270, 496, 672 などが挙げられます。また、すべての完全数(6, 28, 496 など)は必ずオーレ数になることが知られています。「√n まで探索して約数を列挙 → 調和平均を計算 → 整数かどうか判定」という流れをおさえれば、効率よく実装できます。

  1. Pythonで数値が二面素数(Dihedral Prime)かどうかを判定する方法

    ある整数nが与えられたとき、それが「二面素数(dihedral prime)」であるかどうかを判定する方法を解説します。二面素数とは、その数自体が素数であり、さらに7セグメントディスプレイに表示した際に、表示の向き(通常の向きでも上下逆さまでも)に関わらず、同じ数または別の素数として読み取れる数のことです。例えば、入力がn = 1181の場合、出力はTrueになります。下の数字は上の数字を上下逆さま(180度回転)にして表示したものであり、どちらも素数となっています。アルゴリズムの手順この問題を解くために、以下の手順で進めます。up_side_down() 関数を定義します。引数としてnを受け

  2. Pythonで文字列がバイナリ文字列(0と1のみ)かどうかを判定する方法

    この記事では、与えられた文字列が「0」と「1」だけで構成されているかどうかを確認する方法を解説します。このような文字列はバイナリ文字列と呼ばれます。もし「2」や「3」など他の数字が含まれている場合は、非バイナリ文字列として分類します。set()を使った方法Pythonのset()は重複しない要素のみを格納する性質を持っています。そこで、対象の文字列にset()を適用し、その結果を「0」と「1」だけからなる集合と比較します。両者が一致すれば、その文字列は確実にバイナリ文字列です。また、文字列が「1」のみ、または「0」のみで構成されている場合も考慮する必要があります。そのため、OR条件を使って、集