欧拉第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