背景
《斐波那契数列:定义自然法则的数学》 一书提到,斐波那契数列中连续 10 项的和总是能被 11 整除。这样的小结论,固然可以记下来,但是如果我们有比较通用的办法,来探索斐波那契数列中连续的 m 项的和满足怎样的规律,则更为有趣。
结论
| k | 斐波那契数列中连续 ? 项的和一定能被 k 整除 |
|---|---|
| 2 | 3 |
| 3 | 8 |
| 4 | 6 |
| 5 | 20 |
| 6 | 24 |
| 7 | 16 |
| 8 | 12 |
| 9 | 24 |
| 10 | 60 |
| 11 | 10 |
正文
斐波那契数列
F1=1,F2=1,对满足 n≥3 的 n 而言, Fn=Fn−1+Fn−2。满足这样的规则的数列,我们称其为斐波那契数列。
简单的分析
对比较小的 n 来说, Fn 的值列举如下 ⬇️
| n | Fn |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 5 |
| 6 | 8 |
| 7 | 13 |
| 8 | 21 |
| 9 | 34 |
| 10 | 55 |
| 11 | 89 |
| 12 | 144 |
| 13 | 233 |
| 14 | 377 |
| 15 | 610 |
| 16 | 987 |
| 17 | 1597 |
| 18 | 2584 |
| 19 | 4181 |
| 20 | 6765 |
生成上方表格的 Python3 代码如下 ⬇️
python
print(r'| $n$ | $F_n$ |')
print('| --- | --- |')
curr, next = 1, 1
for i in range(1, 21):
print(f'| ${i}$ | ${curr}$ |')
curr, next = next, (curr + next)
连续 2 项的和
既然想探索连续项的和有什么规律,那么就先看连续 2 项的和吧 ⬇️
| n | Fn | Fn+Fn+1 |
|---|---|---|
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 2 | 5 |
| 4 | 3 | 8 |
| 5 | 5 | 13 |
| 6 | 8 | 21 |
| 7 | 13 | 34 |
| 8 | 21 | 55 |
| 9 | 34 | 89 |
| 10 | 55 | 144 |
考虑到 Fn+2=Fn+Fn+1,那么斐波那契数列中连续 2 项的和仍旧会是数列中的某一项。
连续 3 项的和
我们再看看连续 3 项的和。 Fn+Fn+1+Fn+2=Fn+2+Fn+2=2Fn+2。所以斐波那契数列中,连续 3 项的和,一定是偶数。
一般化的分析
如果逐个观察不同 m 时, m 个连续项的和的规律,可能有点耗时间。我们换个思路,既然是想探索连续 m 项的和的规律,假设连续 m 项的和可以被 k 整除,那么我们只需要分析 Fnmodk 的规律即可。
k=2
我们还是从 2 开始(但是现在分析的是 k=2 的情况)。不难写出以下代码
python
print(r'| $n$ | $F_n$ | $F_n\bmod 2$')
print('| --- | --- | --- |')
curr, next = 1, 1
for i in range(1, 21):
print(f'| ${i}$ | ${curr}$ | ${curr%2}$ |')
curr, next = next, (curr + next)
它生成的表格如下
| n | Fn | Fnmod2 |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 0 |
| 4 | 3 | 1 |
| 5 | 5 | 1 |
| 6 | 8 | 0 |
| 7 | 13 | 1 |
| 8 | 21 | 1 |
| 9 | 34 | 0 |
| 10 | 55 | 1 |
| 11 | 89 | 1 |
| 12 | 144 | 0 |
| 13 | 233 | 1 |
| 14 | 377 | 1 |
| 15 | 610 | 0 |
| 16 | 987 | 1 |
| 17 | 1597 | 1 |
| 18 | 2584 | 0 |
| 19 | 4181 | 1 |
| 20 | 6765 | 1 |
Fnmod2 的规律很明显,它以 1,1,0 为周期,我们可以用数学归纳法证明这个规律是成立的。由此可知,斐波那契数列中连续 3 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+2Fn≡1+1+0≡0(mod2)
所以斐波那契数列中连续 3 项的和可以被 2 整除,这和我们刚才的分析是一致的。
k=3
我们再看 k=3 的情况,将代码稍做调整即可 ⬇️
python
print(r'| $n$ | $F_n$ | $F_n\bmod 3$')
print('| --- | --- | --- |')
curr, next = 1, 1
for i in range(1, 21):
print(f'| ${i}$ | ${curr}$ | ${curr%3}$ |')
curr, next = next, (curr + next)
它生成的表格如下
| n | Fn | Fnmod3 |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 2 |
| 4 | 3 | 0 |
| 5 | 5 | 2 |
| 6 | 8 | 2 |
| 7 | 13 | 1 |
| 8 | 21 | 0 |
| 9 | 34 | 1 |
| 10 | 55 | 1 |
| 11 | 89 | 2 |
| 12 | 144 | 0 |
| 13 | 233 | 2 |
| 14 | 377 | 2 |
| 15 | 610 | 1 |
| 16 | 987 | 0 |
| 17 | 1597 | 1 |
| 18 | 2584 | 1 |
| 19 | 4181 | 2 |
| 20 | 6765 | 0 |
这次的周期稍长一些: 1,1,2,0,2,2,1,0(虽然是观察出来的规律,但是可以用数学归纳法证明其正确性)。
由此可知,斐波那契数列中连续 8 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+7Fn≡1+1+2+0+2+2+1+0≡0(mod3)
所以斐波那契数列的连续 8 项的和,一定能被 3 整除。
k=4,5,6
我们再看 k=4,5,6 的情况,将代码稍做调整即可 ⬇️
python
print(r'| $n$ | $F_n$ | $F_n\bmod 4$ | $F_n\bmod 5$ |$F_n\bmod 6$ |')
print('| --- | --- | --- | --- | --- | ')
curr, next = 1, 1
for i in range(1, 21):
print(f'| ${i}$ | ${curr}$ | ${curr%4}$ | ${curr%5}$ | ${curr%6}$ |')
curr, next = next, (curr + next)
| n | Fn | Fnmod4 | Fnmod5 | Fnmod6 |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 1 | 1 |
| 3 | 2 | 2 | 2 | 2 |
| 4 | 3 | 3 | 3 | 3 |
| 5 | 5 | 1 | 0 | 5 |
| 6 | 8 | 0 | 3 | 2 |
| 7 | 13 | 1 | 3 | 1 |
| 8 | 21 | 1 | 1 | 3 |
| 9 | 34 | 2 | 4 | 4 |
| 10 | 55 | 3 | 0 | 1 |
| 11 | 89 | 1 | 4 | 5 |
| 12 | 144 | 0 | 4 | 0 |
| 13 | 233 | 1 | 3 | 5 |
| 14 | 377 | 1 | 2 | 5 |
| 15 | 610 | 2 | 0 | 4 |
| 16 | 987 | 3 | 2 | 3 |
| 17 | 1597 | 1 | 2 | 1 |
| 18 | 2584 | 0 | 4 | 4 |
| 19 | 4181 | 1 | 1 | 5 |
| 20 | 6765 | 1 | 0 | 3 |
Fnmod4 以 1,1,2,3,1,0 为周期。
由此可知,斐波那契数列中连续 6 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+5Fn≡1+1+2+3+1+0≡0(mod4)
所以斐波那契数列的连续 6 项的和,一定能被 4 整除。
继续分析 k=5,6 的情况时,会发现周期比较长,一眼似乎看不出来周期是什么。此时,我们再换换思路。如果 Fnmodk 这个数列存在某个周期 T,那么
- F1modk=F1+Tmodk
- F2modk=F2+Tmodk
- F3modk=F3+Tmodk
- ⋯
那么 (Fnmodk,Fn+1modk) 这样的数对(这里的小括号表示一对数字)也会以周期 T 重复出现,即
- (F1modk,F2modk)=(F1+Tmodk,F2+Tmodk)
- (F2modk,F3modk)=(F2+Tmodk,F3+Tmodk)
- (F3modk,F4modk)=(F3+Tmodk,F4+Tmodk)
- ⋯
为了方便讨论,我们记 an=(Fnmodk,Fn+1modk)。
0≤(Fnmodk)<k 总是成立,所以 an 的可能取值只有 k×k=k2 个(有的值可能取不到)。根据鸽笼原理, a1,a2,⋯,ak2+1 这 k2+1 个值必然有重复的(因为 an 的可能取值只有 k2 个)。假设第一个重复出现的值为 adup 且 adup=adup−t。注意到
an=(Fnmodk,Fn+1modk)
an+1=(Fn+1modk,Fn+2modk)
Fn+2=Fn+1+Fn
所以
an+1=(Fn+1modk,(Fn+1+Fn)modk)
=(an1,(an0+an1)modk)
也就是说,从 an 可以直接得出 an+1。 既然 adup=adup−t,那么必然有 ⬇️
- adup+1=adup−t+1
- adup+2=adup−t+2
- adup+3=adup−t+3
- ⋯
那么对任意 n≥dup, an=an−t 都成立。
刚才提到从 an 可以直接得出 an+1,那么如果知道 an+1,能否反推出 an 呢?我们试一试 ⬇️
an=(Fnmodk,Fn+1modk)
=((Fn+2−Fn+1)modk,Fn+1modk)
=((an+11−an+10)modk,an+10)
看来从 an+1 也可以直接得出 an。
有趣的部分来了。考虑到 adup=adup−t,根据刚才提到的 "从 an+1 也可以直接得出 an" 可知以下 dup−t 个等式都成立 ⬇️
- adup=adup−t
- adup−1=adup−t−1
- adup−2=adup−t−2
- ⋯
- a1+t=a1
所以 a1+t 会是第一个重复的值,它的值和 a1 相等。如此说来,我们只要找到第一个和 a1 相等的 an( n≥2),就可以得出周期 t=n−1 了。由于 Fnmodk=an0,那么 t 自然也是 Fnmodk 的(一个)周期。
我用 Python3 实现了这样的逻辑 ⬇️ (豆包 提供了一些帮助)
python
import argparse
def main():
parser = argparse.ArgumentParser(description="斐波那契模k周期计算")
parser.add_argument("-k", type=int, required=True, help="取模的k值,正整数")
args = parser.parse_args()
k = args.k
if k <= 0:
raise ValueError("k必须为正整数")
print('```text')
appeared_fib_pairs = set()
fib_pair = (1, 1)
n = 1
seen_num = []
while True:
if fib_pair in appeared_fib_pairs:
break
appeared_fib_pairs.add(fib_pair)
seen_num.append(fib_pair[0])
print(f'{n}: {fib_pair}')
next_fib_pair = (fib_pair[1], (fib_pair[0] + fib_pair[1]) % k)
fib_pair = next_fib_pair
n += 1
print('```')
if sum(seen_num) % k != 0:
return
conclusion = f'''
由此可知,斐波那契数列中连续 ${len(appeared_fib_pairs)}$ 项的和满足 ⬇️ ($m$ 是任意正整数)
$$
\\sum_{{n=m}}^{{n=m+{len(appeared_fib_pairs)-1}}} F_n \\equiv {'+'.join(map(str, seen_num))}\\equiv 0\\pmod {{{k}}}
$$
所以斐波那契数列的连续 ${len(appeared_fib_pairs)}$ 项的和,一定能被 ${k}$ 整除。
'''
print(conclusion)
if __name__ == "__main__":
main()
请将以上代码保存为 find_period.py。运行以下命令可以处理 k=5 的情况
bash
python3 find_period.py -k 5
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 0)
5: (0, 3)
6: (3, 3)
7: (3, 1)
8: (1, 4)
9: (4, 0)
10: (0, 4)
11: (4, 4)
12: (4, 3)
13: (3, 2)
14: (2, 0)
15: (0, 2)
16: (2, 2)
17: (2, 4)
18: (4, 1)
19: (1, 0)
20: (0, 1)
由此可知,斐波那契数列中连续 20 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+19Fn≡1+1+2+3+0+3+3+1+4+0+4+4+3+2+0+2+2+4+1+0≡0(mod5)
所以斐波那契数列的连续 20 项的和,一定能被 5 整除。
运行以下命令可以处理 k=6 的情况
bash
python3 find_period.py -k 6
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 5)
5: (5, 2)
6: (2, 1)
7: (1, 3)
8: (3, 4)
9: (4, 1)
10: (1, 5)
11: (5, 0)
12: (0, 5)
13: (5, 5)
14: (5, 4)
15: (4, 3)
16: (3, 1)
17: (1, 4)
18: (4, 5)
19: (5, 3)
20: (3, 2)
21: (2, 5)
22: (5, 1)
23: (1, 0)
24: (0, 1)
由此可知,斐波那契数列中连续 24 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+23Fn≡1+1+2+3+5+2+1+3+4+1+5+0+5+5+4+3+1+4+5+3+2+5+1+0≡0(mod6)
所以斐波那契数列的连续 24 项的和,一定能被 6 整除。
k=7,8,9,10
我们再看 k=7,8,9,10 的情况。
运行以下命令可以处理 k=7 的情况
bash
python3 find_period.py -k 7
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 5)
5: (5, 1)
6: (1, 6)
7: (6, 0)
8: (0, 6)
9: (6, 6)
10: (6, 5)
11: (5, 4)
12: (4, 2)
13: (2, 6)
14: (6, 1)
15: (1, 0)
16: (0, 1)
由此可知,斐波那契数列中连续 16 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+15Fn≡1+1+2+3+5+1+6+0+6+6+5+4+2+6+1+0≡0(mod7)
所以斐波那契数列的连续 16 项的和,一定能被 7 整除。
运行以下命令可以处理 k=8 的情况
bash
python3 find_period.py -k 8
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 5)
5: (5, 0)
6: (0, 5)
7: (5, 5)
8: (5, 2)
9: (2, 7)
10: (7, 1)
11: (1, 0)
12: (0, 1)
由此可知,斐波那契数列中连续 12 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+11Fn≡1+1+2+3+5+0+5+5+2+7+1+0≡0(mod8)
所以斐波那契数列的连续 12 项的和,一定能被 8 整除。
运行以下命令可以处理 k=9 的情况
bash
python3 find_period.py -k 9
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 5)
5: (5, 8)
6: (8, 4)
7: (4, 3)
8: (3, 7)
9: (7, 1)
10: (1, 8)
11: (8, 0)
12: (0, 8)
13: (8, 8)
14: (8, 7)
15: (7, 6)
16: (6, 4)
17: (4, 1)
18: (1, 5)
19: (5, 6)
20: (6, 2)
21: (2, 8)
22: (8, 1)
23: (1, 0)
24: (0, 1)
由此可知,斐波那契数列中连续 24 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+23Fn≡1+1+2+3+5+8+4+3+7+1+8+0+8+8+7+6+4+1+5+6+2+8+1+0≡0(mod9)
所以斐波那契数列的连续 24 项的和,一定能被 9 整除
k=10 的情况,我在 斐波那契数列的个位数出现的周期是多少? 一文里专门进行了讨论。
运行以下命令可以处理 k=10 的情况
bash
python3 find_period.py -k 10
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 5)
5: (5, 8)
6: (8, 3)
7: (3, 1)
8: (1, 4)
9: (4, 5)
10: (5, 9)
11: (9, 4)
12: (4, 3)
13: (3, 7)
14: (7, 0)
15: (0, 7)
16: (7, 7)
17: (7, 4)
18: (4, 1)
19: (1, 5)
20: (5, 6)
21: (6, 1)
22: (1, 7)
23: (7, 8)
24: (8, 5)
25: (5, 3)
26: (3, 8)
27: (8, 1)
28: (1, 9)
29: (9, 0)
30: (0, 9)
31: (9, 9)
32: (9, 8)
33: (8, 7)
34: (7, 5)
35: (5, 2)
36: (2, 7)
37: (7, 9)
38: (9, 6)
39: (6, 5)
40: (5, 1)
41: (1, 6)
42: (6, 7)
43: (7, 3)
44: (3, 0)
45: (0, 3)
46: (3, 3)
47: (3, 6)
48: (6, 9)
49: (9, 5)
50: (5, 4)
51: (4, 9)
52: (9, 3)
53: (3, 2)
54: (2, 5)
55: (5, 7)
56: (7, 2)
57: (2, 9)
58: (9, 1)
59: (1, 0)
60: (0, 1)
由此可知,斐波那契数列中连续 60 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+59Fn≡1+1+2+3+5+8+3+1+4+5+9+4+3+7+0+7+7+4+1+5+6+1+7+8+5+3+8+1+9+0+9+9+8+7+5+2+7+9+6+5+1+6+7+3+0+3+3+6+9+5+4+9+3+2+5+7+2+9+1+0≡0(mod10)
所以斐波那契数列的连续 60 项的和,一定能被 10 整除。
k=11 的情况
运行以下命令可以处理 k=11 的情况
bash
python3 find_period.py -k 11
完整的运行结果如下
text
1: (1, 1)
2: (1, 2)
3: (2, 3)
4: (3, 5)
5: (5, 8)
6: (8, 2)
7: (2, 10)
8: (10, 1)
9: (1, 0)
10: (0, 1)
由此可知,斐波那契数列中连续 10 项的和满足 ⬇️ ( m 是任意正整数)
n=m∑n=m+9Fn≡1+1+2+3+5+8+2+10+1+0≡0(mod11)
所以斐波那契数列的连续 10 项的和,一定能被 11 整除。