欧拉第44题「五边形数」完整解法
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user