Compare commits

...

4 Commits

Author SHA1 Message Date
e5868c2649 feat(0046.GoldbachsConjecture):添加欧拉项目第46题解决方案
📝 docs(0046.GoldbachsConjecture):添加问题描述和解题思路说明
2026-02-03 14:35:55 +08:00
a660ce3942 feat(euler_45):添加欧拉项目第45题解决方案
📝 docs(euler_45):添加详细数学推导和佩尔方程说明文档
2026-01-26 15:36:19 +08:00
e44581dda3 44题解法说明 2026-01-25 22:36:57 +08:00
589732357d 欧拉第44题「五边形数」完整解法 2026-01-25 22:33:39 +08:00
6 changed files with 793 additions and 0 deletions

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()

View File

@@ -0,0 +1,16 @@
要找到一对五边形数 $P_j$ 和 $P_k$,使得它们的和与差都是五边形数,且差 $D = |P_j - P_k|$ 最小,可以采用以下数学方法:
设 $P(n) = \frac{n(3n-1)}{2}$。我们需要找到正整数 $a > b$ 和 $c, d$,满足:
$P(a) - P(b) = P(d), \quad P(a) + P(b) = P(c).$
由此可得:
$P(a) = \frac{P(c) + P(d)}{2}, \quad P(b) = \frac{P(c) - P(d)}{2}.$
令 $u = a - b$$v = a + b$,则原方程化为:
$u(3v - 1) = d(3d - 1) \tag{A}$
$3(v^2 + u^2) - 2v = 2c(3c - 1) \tag{B}$
为了最小化 $D = P(d)$,从 $d = 1$ 开始递增,对每个 $d$ 计算 $M = d(3d - 1)$。将 $M$ 分解为两个正整数因子 $u$ 和 $w$,使得 $w = 3v - 1$,因此 $w \equiv 2 \pmod{3}$。令 $v = \frac{w+1}{3}$,检查 $u$ 和 $v$ 是否同奇偶(以确保 $a = \frac{v+u}{2}$ 和 $b = \frac{v-u}{2}$ 为整数)。然后计算 $a$ 和 $b$,并验证 $P(a) + P(b)$ 是否为五边形数,即判别式 $\Delta = 1 + 24(P(a) + P(b))$ 是否为完全平方数,且 $\sqrt{\Delta} \equiv 5 \pmod{6}$。
按此方法搜索,当 $d = 1912$ 时,得到 $P(d) = 5482660$,且存在 $a = 2167$$b = 1020$,满足条件:
$P(2167) = 7042750, \quad P(1020) = 1560090,$
$P(2167) - P(1020) = 5482660 = P(1912),$
$P(2167) + P(1020) = 8602840 = P(2395).$
因此,最小的 $D$ 值为 $5482660$。

View File

@@ -0,0 +1,86 @@
"""
Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:
Triangle: T_n = n(n+1)/2
Pentagonal: P_n = n(3n-1)/2
Hexagonal: H_n = n(2n-1)
It can be verified that T_285 = P_165 = H_143 = 40755.
Find the next triangle number that is also pentagonal and hexagonal.
"""
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 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
def is_hexagonal(x):
"""检查一个数是否为六边形数"""
# 解方程 n(2n-1) = x => 2n² - n - x = 0
# 判别式 Δ = 1 + 8x 必须是完全平方数
delta = 1 + 8 * x
sqrt_delta = int(delta**0.5)
if sqrt_delta * sqrt_delta != delta:
return False
# 并且 (1 + sqrt(Δ)) ≡ 0 mod 4
return (1 + sqrt_delta) % 4 == 0
@timer
def main() -> None:
n = 286
while True:
triangle = n * (n + 1) // 2
# 直接使用已有的验证函数,避免重复计算
if is_pentagonal(triangle) and is_hexagonal(triangle):
# 找到后计算对应的索引
pent_index = (1 + int((1 + 24 * triangle) ** 0.5)) // 6
hex_index = (1 + int((1 + 8 * triangle) ** 0.5)) // 4
print(f"Answer: T({n})=P({pent_index})=H({hex_index})={triangle}")
break
n += 1
@timer
def main_quick_math(nth: int = 2) -> None:
u = 5
v = 3
sn = 0
while True:
u, v = (2 * u + 3 * v), (u + 2 * v)
if u % 6 == 5 and v % 4 == 3:
k = (u + 1) // 6
j = (v + 1) // 4
n = 2 * j - 1
sn += 1
if sn == nth:
print(f"Answer: T({n})=P({k})=H({j})={n * (n + 1) // 2}")
break
if __name__ == "__main__":
main()
main_quick_math()

View File

@@ -0,0 +1,501 @@
三角形数、五边形数和六边形数之间有一个重要关系:**每一个六边形数都是三角形数**。具体来说,六边形数 \(H_n = n(2n-1)\) 等于三角形数 \(T_{2n-1} = (2n-1)(2n)/2 = n(2n-1)\)。因此,问题转化为寻找**同时是五边形数和六边形数**的数(这样的数自动是三角形数)。
已知 \(T_{285} = P_{165} = H_{143} = 40755\),需要找到下一个这样的数。利用五边形数和六边形数的公式,设 \(P_k = H_j\),得到方程:
\[
k(3k-1)/2 = j(2j-1)
\]
两边乘以2并整理得
\[
3k^2 - k = 4j^2 - 2j
\]
通过配方,引入变量 \(u = 6k - 1\) 和 \(v = 4j - 1\),可将其转化为佩尔方程:
\[
u^2 - 3v^2 = -2
\]
其中 \(u \equiv 5 \pmod{6}\)\(v \equiv 3 \pmod{4}\) 以保证 \(k\) 和 \(j\) 为整数。
该方程的解可通过迭代生成:若 \((u, v)\) 是一组解,则下一组解为 \((u', v') = (2u + 3v, u + 2v)\)。从已知解 \((u, v) = (989, 571)\)(对应 40755开始迭代并检查同余条件得到下一组满足条件的解为 \((191861, 110771)\)。
由此计算出:
- \(k = (u + 1)/6 = 31977\)
- \(j = (v + 1)/4 = 27693\)
对应的数为:
\[
x = P_k = \frac{k(3k-1)}{2} = \frac{31977 \times 95930}{2} = 1533776805
\]
验证可知该数同时也是六边形数和三角形数。
因此,下一个同时是三角形数、五边形数和六边形数的数是 **1533776805**
---
# 关于 佩尔方程 Pell's Equation
下面从**历史来源、基本定义与形式、解的存在性与结构、典型求解方法、解之间的关系、广义佩尔方程及应用**等方面,对佩尔方程做一个系统、全面且尽量直观的介绍。
---
## 一、历史来源与名称由来
### 1.1 古印度的起源
佩尔方程实质上起源很早,最系统的早期研究来自古印度数学校派:
- 7世纪的 **Brahmagupta婆罗摩笈多** 就研究了形如
\[
x^2 - Dy^2 = 1 \quad\text{或}\quad x^2 - Dy^2 = k
\]
的方程。他提出了著名的 **“复合公式composition”**:如果
\[
x_1^2 - Dy_1^2 = n_1,\quad x_2^2 - Dy_2^2 = n_2
\]
\[
(x_1x_2 + D y_1 y_2)^2 - D(x_1y_2 + x_2y_1)^2 = n_1 n_2
\]
从而可以“复合”已有解构造新解,这是后世单位理论和解结构的雏形。
- 后来的印度数学家如 **Bhaskara II、Narayana Pandit** 等,发展了著名的 **Chakravala循环法** 算法,这是一种求解佩尔型方程的迭代算法,在计算效率和思想深度上都相当先进[1][2][3]。
### 1.2 欧洲的再发现与系统化
- 17世纪**Fermat费马** 在给欧洲同行的挑战中多次提出这类方程,要求找到对
\[
x^2 - Dy^2 = 1
\]
的普遍解法。
- 英国数学家 **Brouncker布朗克** 利用连分数方法最早给出了一般解法[1][2][4]。
- 18世纪**Lagrange拉格朗日** 从连分数理论出发,给出了系统而完整的理论(包括“对任意非平方正整数 D总存在无穷多解”的严格证明
### 1.3 “佩尔方程”名称的误会
- 18世纪的 **Euler欧拉** 在论述这类方程时,误将相关成果归功于英国数学家 **John Pell**,而实际上 Pell 本人在该方程上的贡献并不突出。
- 这个误会流传开来方程被称作“Pell's equation”中文常译为 **佩尔方程**[1][3][6][9]。
总结:**佩尔方程起源于印度,被费马等人推动进入欧洲视野,拉格朗日完成理论化,最终却误以 Pell 命名。**
---
## 二、基本定义与形式
### 2.1 标准佩尔方程
通常所说的“佩尔方程”是指:
\[
x^2 - Dy^2 = 1
\]
其中:
- \(D\) 为正整数,且 **不是完全平方数**(若为完全平方则问题退化)。
- 要求 \(x,y\) 为整数(常常关注正整数解)。
若 \(D\) 是完全平方数,例如 \(D = k^2\),则
\[
x^2 - k^2 y^2 = (x - ky)(x + ky) = 1
\]
整数解只有平凡解 \((x,y) = (\pm1, 0)\),因此在数论中通常只考虑 **\(D\) 非平方**的情况。
### 2.2 负佩尔方程
另一个常见的变体是
\[
x^2 - Dy^2 = -1
\]
通常称为 **负佩尔方程**。是否存在解取决于 \(D\) 的性质,尤其与 \(\sqrt{D}\) 的连分数展开 **周期长度的奇偶性** 有关(下文会提到)。
### 2.3 广义佩尔方程
再推广一步,可以考虑
\[
x^2 - Dy^2 = N
\]
其中 \(N\) 为任意整数。这类方程常称为 **广义佩尔方程generalized Pell equation**[2][3][5][7]。
- 当 \(N = 1\) 就是标准佩尔方程。
- 当 \(N = -1\) 即负佩尔方程。
- 一般 \(N\) 的解的存在性和结构与标准方程的解有密切联系。
---
## 三、解的存在性与基本结构
### 3.1 拉格朗日定理:总有无穷多解
**定理Lagrange**
对任意非平方正整数 \(D\),方程
\[
x^2 - Dy^2 = 1
\]
在整数中有 **无限多组非平凡解** \((x,y)\)[1][2][3][6]。
这意味着:
- 不仅总有解,而且解集非常丰富。
- 所有正整数解中存在**一组最小的正解** \((x_1,y_1)\),称为 **基本解 / 最小解 / fundamental solution**
- 其他所有正整数解都可以从这组基本解“生成”。
### 3.2 解的指数结构
一个非常重要的结构结论是:
> 若 \((x_1, y_1)\) 是 \(x^2 - Dy^2 = 1\) 的基本解,则所有正整数解 \((x_n,y_n)\) 可以用
> \[
> x_n + y_n\sqrt{D} = (x_1 + y_1\sqrt{D})^n,\quad n = 1,2,3,\dots
> \]
> 来表示。
其中:
- \(n = 1\) 时就是基本解;
- 对每个 \(n\)\((x_n,y_n)\) 都是整数解;
- 不同的 \(n\) 给出互不相同的解。
这实际上利用了二次域 \(\mathbb{Q}(\sqrt{D})\) 中的“单位”(范数为 1 的代数整数),即:
\[
N(x + y\sqrt{D}) = (x + y\sqrt{D})(x - y\sqrt{D}) = x^2 - Dy^2
\]
佩尔方程的解正是 **范数为 1 的单位元**
---
## 四、典型求解方法:为什么连分数如此核心?
佩尔方程最实用、也最经典的求解方法是 **连分数法continued fractions**。其核心在于一个深刻的事实:
> **\(\sqrt{D}\) 的连分数展开是周期性的;
> 佩尔方程的解可以通过其连分数的收敛分数convergents获得。**
### 4.1 \(\sqrt{D}\) 的连分数展开
对于 \(D\) 非平方,\(\sqrt{D}\) 是无理数,它的连分数展开形式是
\[
\sqrt{D} = [a_0; a_1, a_2, \dots] =
a_0 + \cfrac{1}{a_1 + \cfrac{1}{a_2 + \cdots}}
\]
且有一个重要结论[1][3][6][10]
- 该连分数是 **纯周期的(自某处起循环)**
\[
\sqrt{D} = [a_0; \overline{a_1, a_2, \dots, a_n}]
\]
上面的横线表示 \((a_1,\dots,a_n)\) 反复循环。
- 这个周期长度 \(n\)(有时也写作 \(\ell\))决定了佩尔方程解的结构,尤其和**负佩尔方程是否有解**有强关联。
### 4.2 收敛分数与基本解
连分数的第 \(k\) 个 **收敛分数** \(p_k/q_k\) 由递推公式给出:
\[
\begin{cases}
p_{-2}=0,\; p_{-1}=1 \\
q_{-2}=1,\; q_{-1}=0 \\
p_k = a_k p_{k-1} + p_{k-2} \\
q_k = a_k q_{k-1} + q_{k-2}
\end{cases}
\]
关键事实:
- 对某些 \(k\)\((x,y)=(p_k,q_k)\) 会满足 \(x^2 - Dy^2 = \pm 1\)。
- 周期长度的奇偶决定我们应看第几个收敛分数来得到**基本解**。
更具体地(略去严密证明,只给结论):
- 若周期长度 \(n\) 为 **偶数**,则
基本解来自 “周期结束位置”的收敛分数。
- 若周期长度 \(n\) 为 **奇数**,则
通常需要看“两个周期”的收敛分数,即更靠后的一项。
典型例子:
\(\sqrt{61}\) 的连分数为
\[
\sqrt{61} = [7; \overline{1,4,3,1,2,2,1,3,4,1,14}]
\]
周期长度为 11奇数对应的基本解为
\[
x_1 = 1766319049,\quad y_1 = 226153980
\]
这是一个非常大的解,说明基本解 **可能极其巨大**(这在计算理论上非常重要)。
### 4.3 Chakravala循环法
另一个经典方法是印度的 **Chakravala algorithm**(循环法)[2][3][5]
- 通过从“近似解”开始,不断调整,使
\[
x^2 - Dy^2 = k
\]
中的绝对值 \(|k|\) 逐步缩小,最终达到 \(k = \pm1\)。
- 每一步更新利用类似 Brahmagupta 复合公式的构造。
- 在很多 \(D\) 的情形下,它比直接算连分数更高效。
现代教材多以连分数为主但在历史与算法思想上Chakravala 非常值得单独研究。
---
## 五、解之间的关系与递推公式
### 5.1 “乘法封闭”与单位群结构
设 \((x_1,y_1)\) 和 \((x_2,y_2)\) 均是
\[
x^2 - Dy^2 = 1
\]
的解,则考虑
\[
(x_1 + y_1\sqrt{D})(x_2 + y_2\sqrt{D}) =
(x_3 + y_3\sqrt{D})
\]
展开可得:
\[
x_3 = x_1x_2 + Dy_1y_2,\quad
y_3 = x_1y_2 + x_2y_1
\]
可以验证:
\[
x_3^2 - Dy_3^2 = (x_1^2 - Dy_1^2)(x_2^2 - Dy_2^2) = 1\cdot1 = 1
\]
即:**两个解的“乘法”仍是解**[2][6][8]。这说明佩尔方程解在运算
\[
(x,y) \cdot (x',y') = (x x' + D y y',\, x y' + x' y)
\]
下形成一个 **阿贝尔群**,这本质上就是 \(\mathbb{Z}[\sqrt{D}]\) 中单位元群。
### 5.2 从基本解生成所有解:指数关系
如前所述,若 \((x_1,y_1)\) 是基本解,则
\[
x_n + y_n\sqrt{D} = (x_1 + y_1\sqrt{D})^n
\]
因此得到显式递推公式(可由二项式展开得到):
- 一阶递推:
\[
\begin{cases}
x_{n+1} = x_1 x_n + D y_1 y_n \\
y_{n+1} = x_1 y_n + y_1 x_n
\end{cases}
\]
- 二阶线性递推(只用 \(x_n\) 自身):
\[
x_{n+1} = 2 x_1 x_n - x_{n-1},\quad
y_{n+1} = 2 x_1 y_n - y_{n-1}
\]
这是因为 \((x_1 + y_1\sqrt{D})\) 类似“特征根”,解序列是形如 \(\lambda^n\) 的线性递推。
这些递推在研究解的增长速度、解中出现“完全幂”等性质时非常有用[8][9]。
---
## 六、广义佩尔方程 \(x^2 - Dy^2 = N\)
### 6.1 基本结构
广义佩尔方程:
\[
x^2 - Dy^2 = N
\]
其中 \(D\) 非平方,\(N\) 为任意整数[2][3][5][7]。
核心事实:
- 若存在 **一个**整数解 \((x_0,y_0)\),且标准佩尔方程有基本解 \((x_1,y_1)\),则
所有解都可以写成
\[
x + y\sqrt{D} = (x_0 + y_0\sqrt{D})(x_1 + y_1\sqrt{D})^n,\quad n\in\mathbb{Z}
\]
- 即:解的集合是“单位群轨道上的一个整点”。
更直观地说:
1. **先解标准方程** \(x^2 - Dy^2 = 1\),求出单位元 \(u = x_1 + y_1\sqrt{D}\)
2. 若能找到一个满足 \(x^2 - Dy^2 = N\) 的特解 \(v = x_0 + y_0\sqrt{D}\)
3. 则所有解都是 \(v, uv, u^2 v, u^3 v, ...\) 这一无限序列中的整数点。
### 6.2 解的存在性与条件
- 广义方程并不总有解,它的可解性与模 \(D\) 的二次剩余、类群结构等深层理论有关。
- 一旦有一个解,通常便会有无穷多解,这是因为可以不断乘以单位元 \(u\)。
在具体计算中,常先通过模数检查、有限搜索或用连分数辅助找到一个特解,再用标准佩尔方程的单位元生成全部解。
---
## 七、佩尔方程通常解决或涉及哪些问题?
佩尔方程本身就是经典的丢番图问题,但它也广泛出现在以下情景中:
### 7.1 有理逼近与“最佳逼近”
- 连分数理论告诉我们:连分数的收敛分数 \(p_k/q_k\) 给出对实数 \(\alpha\) 的 **最佳有理逼近**
- 对 \(\alpha = \sqrt{D}\) 而言,满足
\[
\left| \sqrt{D} - \frac{x}{y} \right|
\]
非常小的分数 \(\frac{x}{y}\) 常常来自佩尔方程解,因为若
\[
x^2 - Dy^2 = \pm 1
\]
\[
\left|\sqrt{D} - \frac{x}{y}\right|
= \left|\frac{x^2 - Dy^2}{y(\sqrt{D} + x/y)}\right|
\approx \frac{1}{2 \sqrt{D} y^2}
\]
- 因此,佩尔方程的解经常用于构造**对平方根的极优有理近似**。
### 7.2 二次域与代数数论中的单位问题
在二次代数数域 \(\mathbb{Q}(\sqrt{D})\) 中:
- 环 \(\mathbb{Z}[\sqrt{D}]\) 的单位元集合与佩尔方程的解一一对应:
\[
N(x + y\sqrt{D}) = x^2 - Dy^2 = \pm 1
\]
- 研究单位元结构Dirichlet 单位定理的特例)即是在研究佩尔方程。
- 类数、理想分解、模形式等更高阶理论中,都频繁出现佩尔方程及其广义形式[3][7][9]。
### 7.3 组合、几何与图论中的出现
- 一些关于 **整数点格、几何图形面积** 的问题会转化为方程 \(x^2 - Dy^2 = N\)
- 在某些组合结构(例如 dessins d'enfants 的不变量研究)中也出现佩尔方程[7]。
### 7.4 密码学与算法复杂度
- 佩尔方程提供了构造**巨大整数对**的自然途径,可用于某些密码构造或伪随机数生成;
- 同时也出现在对某些加密算法的攻击分析中;
- 在计算复杂性研究中,用来测试数论算法的效率。
---
## 八、具体例子与直观体会
### 8.1 小 D 的基本解示例
根据理论和连分数计算,可得到若干典型 D 的基本解(这里列出部分)[1][2][3][6]
| \(D\) | 基本解 \((x_1, y_1)\) |
|------|----------------------|
| 2 | (3, 2) |
| 3 | (2, 1) |
| 5 | (9, 4) |
| 6 | (5, 2) |
| 7 | (8, 3) |
| 8 | (3, 1) |
| 10 | (19, 6) |
| 11 | (10, 3) |
| 12 | (7, 2) |
| 14 | (15, 4) |
| 15 | (4, 1) |
| 17 | (33, 8) |
| 18 | (17, 4) |
| 19 | (170, 39) |
| 20 | (9, 2) |
| 21 | (55, 12) |
| 22 | (197, 42) |
| 23 | (24, 5) |
| 24 | (5, 1) |
| 28 | (127, 24) |
| 31 | (1520, 273) |
| 43 | (3482, 531) |
| 46 | (24335, 3588) |
| 61 | (1766319049, 226153980) |
可以看到:
- 有的 \(D\)(如 2,3,5基本解较小
- 有的 \(D\)(如 61基本解极大这正是为什么佩尔方程在计算机上求解仍然具有挑战性。
### 8.2 利用递推获得更高阶解的感受
以 \(D = 2\) 为例,方程
\[
x^2 - 2y^2 = 1
\]
基本解为 \((3,2)\)。则第二个解由
\[
x_2 + y_2\sqrt{2} = (3 + 2\sqrt{2})^2 = 17 + 12\sqrt{2}
\]
即 \((x_2,y_2) = (17,12)\),验证:
\[
17^2 - 2\cdot 12^2 = 289 - 288 = 1
\]
第三个解:
\[
(3 + 2\sqrt{2})^3 = 99 + 70\sqrt{2} \Rightarrow (x_3,y_3) = (99,70)
\]
解的规模指数增长,这种**指数级膨胀**是佩尔方程序列的一大特征。
---
## 九、总结:佩尔方程的内涵与价值
综合上述内容,可以从几个角度理解佩尔方程的“全貌”:
1. **来源**
- 起源于古印度的丢番图方程研究,是 BrahmaguptaBhaskaraChakravala 传统的重要对象;
- 17世纪由 Fermat 挑战推动Brouncker 首给欧洲解法18世纪 Lagrange 完成理论统一;
- 名称源自 Euler 的误归功John Pell 实际贡献有限。
2. **通常解决的问题**
- 经典丢番图问题:给定非平方 \(D\),求所有整数解 \((x,y)\) 使 \(x^2 - Dy^2 = 1\)
- 给出 \(\sqrt{D}\) 的最佳有理逼近;
- 在二次代数数域中,描述环 \(\mathbb{Z}[\sqrt{D}]\) 的单位元结构;
- 为广义方程 \(x^2 - Dy^2 = N\) 提供单位群背景,从而刻画其全部解;
- 在密码学、几何、图论等领域,作为子问题或工具频繁出现。
3. **解的关系与结构**
- 存在唯一(在正象限)的**最小正解** \((x_1,y_1)\),称为基本解;
- 所有解满足
\[
x_n + y_n\sqrt{D} = (x_1 + y_1\sqrt{D})^n
\]
呈现指数结构;
- 两个解的“乘积”仍是解,形成单位群,递推关系
\[
x_{n+1} = x_1x_n + Dy_1y_n,\quad y_{n+1} = x_1y_n + y_1x_n
\]
或二阶线性递推形式;
- 对广义方程 \(x^2 - Dy^2 = N\),一旦有一个特解 \((x_0,y_0)\),所有解由
\[
(x_0 + y_0\sqrt{D})(x_1 + y_1\sqrt{D})^n
\]
给出。
4. **解法的核心思路**
- 通过 \(\sqrt{D}\) 的 **连分数展开** 及其收敛分数,找到基本解;
- 或用 Chakravala 循环法等算法迭代逼近;
- 本质上都是在寻找“范数为 1 的单位”。
佩尔方程表面上只是一个简单的二次方程,但它串联了:
- 古典丢番图方程;
- 连分数与最优有理逼近;
- 代数数论中的单位与范数;
- 算法数论和复杂性问题。
从历史、理论到算法与应用,都是一个非常典型又极具深度的数学对象。
---
### References
[1] Pell's equation. <https://en.wikipedia.org/wiki/Pell's_equation>
[2] Pell equation - AoPS Wiki. <https://artofproblemsolving.com/wiki/index.php/Pell_equation>
[3] Pell Equation -- Wolfram MathWorld. <https://mathworld.wolfram.com/PellEquation.html>
[4] Pell's equation - MacTutor History of Mathematics. <https://mathshistory.st-andrews.ac.uk/HistTopics/Pell/>
[5] PELL'S EQUATION, I & II, by K. Conrad (PDFs). <https://kconrad.math.uconn.edu/blurbs/ugradnumthy/pelleqn1.pdf> / <https://kconrad.math.uconn.edu/blurbs/ugradnumthy/pelleqn2.pdf>
[6] Continued Fractions and Pell's Equation (various lecture notes). <https://crypto.stanford.edu/pbc/notes/contfrac/pell.html>
[7] Generalized Pell equations and applications (Stanford / UConn handouts). <http://virtualmath1.stanford.edu/~conrad/154Page/handouts/genpell.pdf>
[8] Recurrence relations for Pell's equation solutions (MathStackExchange, etc.). <https://math.stackexchange.com/questions/2932750/recurrence-relation-for-pells-equation-x2-2y2-1>
[9] On the BrahmaguptaFermatPell Equation. <https://webusers.imj-prg.fr/~michel.waldschmidt/articles/pdf/BrahmaguptaFermatPellEn.pdf>
[10] Continued fractions and Pell's equation (expository PDFs). <https://www.math.uchicago.edu/~may/VIGRE/VIGRE2008/REUPapers/Yang.pdf>

View File

@@ -0,0 +1,81 @@
"""
It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square.
9 = 7 + 2 * 1^2
15 = 7 + 2 * 2^2
21 = 3 + 2 * 3^2
25 = 7 + 2 * 3^2
27 = 19 + 2 * 2^2
33 = 31 + 2 * 1^2
It turns out that the conjecture was false.
What is the smallest odd composite that cannot be written as the sum of a prime and twice a square?
"""
import math
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__} took {end_time - start_time:.6f} seconds")
return result
return wrapper
def sieve_of_eratosthenes(limit: int = 5000) -> list[bool]:
"""生成一个布尔数组is_prime[i]为True表示i是质数"""
is_prime = [True] * (limit + 1)
is_prime[0:2] = [False, False]
for i in range(2, int(limit**0.5) + 1):
if is_prime[i]:
for j in range(i * i, limit + 1, i):
is_prime[j] = False
return is_prime
def optimized_find_counterexamples(limit: int = 10000) -> list[int]:
"""
优化版本,使用集合提高查找效率
"""
# 生成质数表
is_prime = sieve_of_eratosthenes(limit)
primes = [i for i in range(limit + 1) if is_prime[i]]
# 预计算所有奇合数
odd_composites = set(n for n in range(3, limit + 1, 2) if not is_prime[n])
# 预计算2k²的值
max_k = int(math.sqrt(limit / 2)) + 1
two_k_squared = [2 * k * k for k in range(1, max_k + 1)]
# 计算所有可以表示的奇合数
representable_odd_composites = set()
for p in primes:
if p > limit:
break
for tks in two_k_squared:
n = p + tks
if n > limit:
break
if n in odd_composites:
representable_odd_composites.add(n)
# 找出不能表示的奇合数
return sorted(odd_composites - representable_odd_composites)
@timer
def main(limit: int = 20000) -> None:
res = optimized_find_counterexamples(limit)
for r in res:
print(r)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,4 @@
这个问题,怎么都不算有简洁的方式找到,暴力搜索是唯一途径,但所幸,这个搜索还算快速。
另外,这个问题可以在 [OEIS](https://oeis.org/A060003) 上直接搜索到。
这也算是最简单偷懒的方式了吧。