Compare commits
6 Commits
af1cb88018
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
e5868c2649
|
|||
|
a660ce3942
|
|||
|
e44581dda3
|
|||
|
589732357d
|
|||
|
1c4693c205
|
|||
|
726763d95c
|
2
main.py
2
main.py
@@ -1,7 +1,5 @@
|
||||
import runpy
|
||||
from pathlib import Path
|
||||
from profile import run
|
||||
from tarfile import SOLARIS_XHDTYPE
|
||||
|
||||
import typer
|
||||
|
||||
|
||||
105
solutions/0044.PentagonNums/euler_44.py
Normal file
105
solutions/0044.PentagonNums/euler_44.py
Normal 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()
|
||||
16
solutions/0044.PentagonNums/readme.md
Normal file
16
solutions/0044.PentagonNums/readme.md
Normal 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$。
|
||||
86
solutions/0045.TrianPentaHexa/euler_45.py
Normal file
86
solutions/0045.TrianPentaHexa/euler_45.py
Normal 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()
|
||||
501
solutions/0045.TrianPentaHexa/readme.md
Normal file
501
solutions/0045.TrianPentaHexa/readme.md
Normal 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. **来源**
|
||||
- 起源于古印度的丢番图方程研究,是 Brahmagupta–Bhaskara–Chakravala 传统的重要对象;
|
||||
- 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 Brahmagupta–Fermat–Pell 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>
|
||||
81
solutions/0046.GoldbachsConjecture/euler_46.py
Normal file
81
solutions/0046.GoldbachsConjecture/euler_46.py
Normal 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()
|
||||
4
solutions/0046.GoldbachsConjecture/readme.md
Normal file
4
solutions/0046.GoldbachsConjecture/readme.md
Normal file
@@ -0,0 +1,4 @@
|
||||
这个问题,怎么都不算有简洁的方式找到,暴力搜索是唯一途径,但所幸,这个搜索还算快速。
|
||||
|
||||
另外,这个问题可以在 [OEIS](https://oeis.org/A060003) 上直接搜索到。
|
||||
这也算是最简单偷懒的方式了吧。
|
||||
Reference in New Issue
Block a user