欧拉第44题「五边形数」完整解法

This commit is contained in:
2026-01-25 22:33:39 +08:00
parent 1c4693c205
commit 589732357d

View File

@@ -0,0 +1,105 @@
"""
Pentagonal numbers are generated by the formula, P(n) = n(3n - 1)/2.
The first ten pentagonal numbers are:
1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...
It can be seen that P(4) + P(7) = 22 + 70 = 92 = P(8).
However, their difference, 70 - 22 = 48 , is not pentagonal.
Find the pair of pentagonal numbers, P_j and P_k,
for which their sum and difference are pentagonal and D = |P_j - P_k| is minimised; what is the value of D ?
"""
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} taken: {end_time - start_time:.6f} seconds")
return result
return wrapper
def pentagonal(n):
return n * (3 * n - 1) // 2
def is_pentagonal(x):
"""检查一个数是否为五边形数"""
# 解方程 n(3n-1)/2 = x => 3n² - n - 2x = 0
# 判别式 Δ = 1 + 24x 必须是完全平方数
delta = 1 + 24 * x
sqrt_delta = int(delta**0.5)
if sqrt_delta * sqrt_delta != delta:
return False
# 并且 (1 + sqrt(Δ)) ≡ 0 mod 6
return (1 + sqrt_delta) % 6 == 0
@timer
def main() -> None:
n = 1
is_quit = False
while not is_quit:
D = pentagonal(n)
M = n * (3 * n - 1)
# 寻找M的所有因子对(u, w)
# 其中u = a-b, w = 3v-1, v = a+b
limit = int(M**0.5)
for u in range(1, limit + 1):
if M % u != 0:
continue
w = M // u
# 检查w ≡ 2 mod 3
if w % 3 != 2:
continue
# 计算v = (w + 1) / 3
v = (w + 1) // 3
# 检查u和v是否同奇偶
if (u % 2) != (v % 2):
continue
# 计算a和b
a = (v + u) // 2
b = (v - u) // 2
# 检查a和b是否为正整数
if b <= 0 or a <= b:
continue
# 计算P(a)和P(b)
Pa = pentagonal(a)
Pb = pentagonal(b)
# 验证Pa - Pb = P(d)
if Pa - Pb != D:
continue
# 验证Pa + Pb是否为五边形数
if is_pentagonal(Pa + Pb):
print("Answer:")
print(f" a = {a}, b = {b}")
print(f" P(a) = {Pa}, P(b) = {Pb}")
print(f" P(a) - P(b) = {D} = P({n})")
print(f" P(a) + P(b) = {Pa + Pb}")
print(
f" Verify that P(a) + P(b) is a pentagonal number: {is_pentagonal(Pa + Pb)}"
)
print(f"D = {D}")
is_quit = True
n += 1
if __name__ == "__main__":
main()