Update fast_fibonacci.py (#1889)

* Update fast_fibonacci.py

* Update fast_fibonacci.py

Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
Sanders Lin 2020-05-20 01:31:52 +08:00 committed by GitHub
parent 0e6e5056b3
commit 777ddca2e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,44 +1,37 @@
#!/usr/bin/python #!/usr/bin/env python3
""" """
This program calculates the nth Fibonacci number in O(log(n)). This program calculates the nth Fibonacci number in O(log(n)).
It's possible to calculate F(1000000) in less than a second. It's possible to calculate F(1_000_000) in less than a second.
""" """
import sys import sys
from typing import Tuple
# returns F(n) def fibonacci(n: int) -> int:
def fibonacci(n: int): # noqa: E999 This syntax is Python 3 only """
return F(n)
>>> [fibonacci(i) for i in range(13)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
"""
if n < 0: if n < 0:
raise ValueError("Negative arguments are not supported") raise ValueError("Negative arguments are not supported")
return _fib(n)[0] return _fib(n)[0]
# returns (F(n), F(n-1)) # returns (F(n), F(n-1))
def _fib(n: int): # noqa: E999 This syntax is Python 3 only def _fib(n: int) -> Tuple[int, int]:
if n == 0: if n == 0: # (F(0), F(1))
# (F(0), F(1))
return (0, 1) return (0, 1)
else:
# F(2n) = F(n)[2F(n+1) F(n)] # F(2n) = F(n)[2F(n+1) F(n)]
# F(2n+1) = F(n+1)^2+F(n)^2 # F(2n+1) = F(n+1)^2+F(n)^2
a, b = _fib(n // 2) a, b = _fib(n // 2)
c = a * (b * 2 - a) c = a * (b * 2 - a)
d = a * a + b * b d = a * a + b * b
if n % 2 == 0: return (d, c + d) if n % 2 else (c, d)
return (c, d)
else:
return (d, c + d)
if __name__ == "__main__": if __name__ == "__main__":
args = sys.argv[1:] n = int(sys.argv[1])
if len(args) != 1: print(f"fibonacci({n}) is {fibonacci(n)}")
print("Too few or too much parameters given.")
exit(1)
try:
n = int(args[0])
except ValueError:
print("Could not convert data to an integer.")
exit(1)
print("F(%d) = %d" % (n, fibonacci(n)))