为什么非常大的斐波那契数列会形成椭圆形?

Why do very large Fibonacci numbers create an ellipse-type shape?

in_range = int(input("range: "))

fibo_list = []

a = 0
b = 1
count = 0

if in_range < 0:
    print("faulty")
elif in_range == 0:
    print("faulty")
else:
    while count < in_range:
        c = a + b
        a = b
        b = c
        count += 1
        fibo_list.append(a)


print(fibo_list)

在这段代码的范围内输入1000时,会生成很多椭圆,有些很难看清。这似乎只发生在斐波那契数列中,而没有其他长数链。这是为什么?

这只是巧合。日蚀由分隔符“,”组成​​,这意味着位置最终取决于数字的长度和显示的宽度。由于数字的长度每次都在 0-1 之间增长,因此行与行之间的位置偏移取决于每行可以容纳多少个数字。如果您尝试打印 10000 :p

,您可能会发现此模式消失或日食的半径发生变化

数字之间的空格"shape"只是将数字对齐宽度(或宽度的倍数)接近终端宽度的产物,而slowly增加位数。斐波那契级数恰好以大致适合看到 "ellipse pattern" 出现的速度增加位数,但任何以类似速度增加位数的模式都会看到这样的模式。也许不在同一个地方,也许曲线稍微平缓或陡峭,但相似。

作为一个简单的例子,打印从 300 到 600 的 1.5 的截断幂会产生一个 非常 相似的模式:

print([int(1.5 ** i) for i in range(300, 600)])

您观察到:

This seems to only happen with the Fibonacci sequence

一些模式可以出现在任何序列中,但使用斐波那契套件它可以稳定到无限大,甚至更精确。你看到了一些更大螺旋的曲线。

在斐波那契数列中取两个连续数,例子:

144 / 89 = 1.6179..

89 / 144 = 0.618..

组中两个连续的数字总是返回相同的比率。

这 (1 + 平方根 (5)) / 2) = 1.618...

并且 (1 - 平方根 (5)) / 2) = 0.618...

这是黄金比例,有很多话要说,这远远超出了编程的范围:

https://en.wikipedia.org/wiki/Golden_ratio

关于编程,黄金比例是避免循环交错的最佳技巧。它在合成器中使用很多。正如我们所见,它适用于时间。用了很多循环,还是很爽的。为了更深入,我建议看看它如何应用于音乐理论和金融技术分析。

这些模式在自然界中很常见,您的文本正在形成这些序列:

与其说这是一个编程问题,不如说这是一个数学问题,但我们可以用代码更轻松地研究它。

此处斐波那契数列唯一相关的特征是数字的字符串长度,即数字的位数。由于斐波那契数列呈指数增长,因此位数近似线性增加,因为以10为底的对数函数告诉你它有多少位数,而对数是指数函数的倒数。

因此我们可以观察到长度线性增加的字符串的相同模式:

>>> print(*( '8'*i for i in range(70, 89) ))
8888888888888888888888888888888888888888888888888888888888888888888888 888888888
88888888888888888888888888888888888888888888888888888888888888 88888888888888888
8888888888888888888888888888888888888888888888888888888 888888888888888888888888
8888888888888888888888888888888888888888888888888 888888888888888888888888888888
88888888888888888888888888888888888888888888 88888888888888888888888888888888888
8888888888888888888888888888888888888888 888888888888888888888888888888888888888
8888888888888888888888888888888888888 888888888888888888888888888888888888888888
88888888888888888888888888888888888 88888888888888888888888888888888888888888888
8888888888888888888888888888888888 888888888888888888888888888888888888888888888
8888888888888888888888888888888888 888888888888888888888888888888888888888888888
88888888888888888888888888888888888 88888888888888888888888888888888888888888888
8888888888888888888888888888888888888 888888888888888888888888888888888888888888
8888888888888888888888888888888888888888 888888888888888888888888888888888888888
88888888888888888888888888888888888888888888 88888888888888888888888888888888888
8888888888888888888888888888888888888888888888888 888888888888888888888888888888
8888888888888888888888888888888888888888888888888888888 888888888888888888888888
88888888888888888888888888888888888888888888888888888888888888 88888888888888888
8888888888888888888888888888888888888888888888888888888888888888888888 888888888
8888888888888888888888888888888888888888888888888888888888888888888888888888888

那么问题来了,为什么线性增加长度的弦会变成这个形状呢?

我特意选择了 70 到 89 之间的长度,因为终端宽度为 80,因此每行放置一个 "gap",大大简化了分析。

  • 当长度为 75 的字符串越过换行符时,下一行的间隔比上一行的间隔 5 spaces 更左 , 因为 75 比 80 少 5.
  • 下一个字符串的长度为 76,所以差距是 4 spaces 再往左
  • 下一个字符串长度是77,所以差距是3 spaces 再往左.
  • 下一个字符串长度是78,所以差距是2spaces再往左.
  • 下一个字符串长度是79,所以差距是1space更左边
  • 下一个字符串长度是 80,所以间隙就在上面那行间隙的正下方 - 0 spaces 再往左 .
  • 下一个字符串长度是81,所以差距是1space更右
  • 下一个字符串的长度是82,所以差距是2space秒.
  • ...等等。

注意这个简单的模式:因为字符串每次都变长 1,所以空隙的相对偏移量在每一行上都会改变 1。这有点像微分方程:d(gap position) / d(line number)是行数的线性函数,所以我们可以通过integrating: gap position is a quadratic function of the line number. That means the shape is a parabola求出间隙的绝对偏移量(不是椭圆)。

一个有点有趣的结果是,如果您将字符串宽度调整到接近终端宽度,您可以绘制任何您喜欢的函数的积分。这是符号函数的积分,看起来像预期的 abs(x)

>>> def sign(x):
...     return -1 if x < 0 else 1 if x > 0 else 0
...
>>> print(*( '8'*(79 + 5*sign(i)) for i in range(-10, 10) ))
88888888888888888888888888888888888888888888888888888888888888888888888888 88888
888888888888888888888888888888888888888888888888888888888888888888888 8888888888
8888888888888888888888888888888888888888888888888888888888888888 888888888888888
88888888888888888888888888888888888888888888888888888888888 88888888888888888888
888888888888888888888888888888888888888888888888888888 8888888888888888888888888
8888888888888888888888888888888888888888888888888 888888888888888888888888888888
88888888888888888888888888888888888888888888 88888888888888888888888888888888888
888888888888888888888888888888888888888 8888888888888888888888888888888888888888
8888888888888888888888888888888888 888888888888888888888888888888888888888888888
88888888888888888888888888888 88888888888888888888888888888888888888888888888888
88888888888888888888888888888 88888888888888888888888888888888888888888888888888
8888888888888888888888888888888888 888888888888888888888888888888888888888888888
888888888888888888888888888888888888888 8888888888888888888888888888888888888888
88888888888888888888888888888888888888888888 88888888888888888888888888888888888
8888888888888888888888888888888888888888888888888 888888888888888888888888888888
888888888888888888888888888888888888888888888888888888 8888888888888888888888888
88888888888888888888888888888888888888888888888888888888888 88888888888888888888
8888888888888888888888888888888888888888888888888888888888888888 888888888888888
888888888888888888888888888888888888888888888888888888888888888888888 8888888888
88888888888888888888888888888888888888888888888888888888888888888888888888