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 はオーレ数であることがわかります。
判定アルゴリズムの手順
オーレ数かどうかの判定は、以下の手順で行えます。
get_all_div():引数 n を受け取り、約数をすべて求める関数を定義します。- 空のリスト div を用意します。
- i を 1 から √n の整数部分までループさせます。
- n が i で割り切れる場合:
- 商(n ÷ i)が i と等しい場合(平方数の場合)は、i だけを div に追加します。
- それ以外の場合は、i と商(n ÷ i)の両方を div に追加します。
get_harmonic_mean():引数 n を受け取り、約数の調和平均を返す関数を定義します。- div = get_all_div(n) で約数リストを取得します。
- total を 0、length を div の要素数とし、各約数 d について total に n ÷ d を加算していきます。
- total を n で割り、最後に length ÷ total を返します(これが調和平均になります)。
- メイン処理では 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 まで探索して約数を列挙 → 調和平均を計算 → 整数かどうか判定」という流れをおさえれば、効率よく実装できます。
-
Pythonで数値が二面素数(Dihedral Prime)かどうかを判定する方法
ある整数nが与えられたとき、それが「二面素数(dihedral prime)」であるかどうかを判定する方法を解説します。二面素数とは、その数自体が素数であり、さらに7セグメントディスプレイに表示した際に、表示の向き(通常の向きでも上下逆さまでも)に関わらず、同じ数または別の素数として読み取れる数のことです。例えば、入力がn = 1181の場合、出力はTrueになります。下の数字は上の数字を上下逆さま(180度回転)にして表示したものであり、どちらも素数となっています。アルゴリズムの手順この問題を解くために、以下の手順で進めます。up_side_down() 関数を定義します。引数としてnを受け
-
Pythonで文字列がバイナリ文字列(0と1のみ)かどうかを判定する方法
この記事では、与えられた文字列が「0」と「1」だけで構成されているかどうかを確認する方法を解説します。このような文字列はバイナリ文字列と呼ばれます。もし「2」や「3」など他の数字が含まれている場合は、非バイナリ文字列として分類します。set()を使った方法Pythonのset()は重複しない要素のみを格納する性質を持っています。そこで、対象の文字列にset()を適用し、その結果を「0」と「1」だけからなる集合と比較します。両者が一致すれば、その文字列は確実にバイナリ文字列です。また、文字列が「1」のみ、または「0」のみで構成されている場合も考慮する必要があります。そのため、OR条件を使って、集