Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

When inputting 1000 for the range of this code, many ellipse shapes are created, some of which are hard to see. This seems to only happen with the Fibonacci sequence and no other chains of long numbers. Why is this?Here is what the ellipses look like

like image 665
Caspian Ahlberg Avatar asked Dec 03 '19 02:12

Caspian Ahlberg


2 Answers

The "shape" of the blank spaces between the numbers is just an artifact of aligning numbers with a width (or multiple of the width) close to the terminal width, while slowly increasing the number of digits. Fibonacci progression just happens to increase the number of digits at a rate that is roughly the right speed to see the "ellipse pattern" appear, but any pattern that grows in digit count at a similar rate will see such a pattern. Maybe not at the same places, maybe slightly gentler or steeper curves, but similar.

Just as a simple example, printing truncated powers of 1.5 from 300 to 600 produces a very similar pattern:

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

Power pattern

like image 50
ShadowRanger Avatar answered Sep 19 '22 18:09

ShadowRanger


This is more of a mathematical question than a programming one, but we can investigate it more easily with code.

The only relevant feature of the Fibonacci sequence here is the string lengths of the numbers, i.e. their number of digits. Since the Fibonacci sequence has exponential growth, the number of digits increases approximately linearly, because the base-10 logarithm function tells you how many digits it has, and a logarithm is the inverse of an exponential function.

So we can observe the same pattern with strings of linearly-increasing length:

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

The question is then, why do strings of linearly increasing length make this shape?

I've purposely selected the lengths from 70 to 89 because the terminal width is 80, so this puts one "gap" on each line, simplifying the analysis considerably.

  • When a string of length 75 runs over the line break, the gap on the next line is 5 spaces further left than the gap on the line above, because 75 is 5 less than 80.
  • The next string has length 76, so the gap is 4 spaces further left.
  • The next string length is 77, so the gap is 3 spaces further left.
  • The next string length is 78, so the gap is 2 spaces further left.
  • The next string length is 79, so the gap is 1 space further left.
  • The next string length is 80, so the gap is directly underneath the gap on the line above - 0 spaces further left.
  • The next string length is 81, so the gap is 1 space further right.
  • The next string length is 82, so the gap is 2 spaces further right.
  • ...and so on.

Notice the simple pattern: because the string gets longer by 1 each time, the relative offset of the gap changes by 1 on each line. This is a bit like a differential equation: d(gap position) / d(line number) is a linear function of the line number, so we can find the absolute offset of the gap by integrating: gap position is a quadratic function of the line number. That means the shape is a parabola (not an ellipse).

A mildly amusing consequence is that if you tune the string width to be near the terminal width, you can draw an integral of any function you like. Here's the integral of the sign function, which looks like abs(x) as expected:

>>> 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
like image 22
kaya3 Avatar answered Sep 17 '22 18:09

kaya3