mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-27 15:01:08 +00:00
bc8df6de31
* [pre-commit.ci] pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.2.2 → v0.3.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.2...v0.3.2) - [github.com/pre-commit/mirrors-mypy: v1.8.0 → v1.9.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.8.0...v1.9.0) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
40 lines
865 B
Python
40 lines
865 B
Python
#!/usr/bin/env python3
|
||
|
||
"""
|
||
This program calculates the nth Fibonacci number in O(log(n)).
|
||
It's possible to calculate F(1_000_000) in less than a second.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
|
||
|
||
def fibonacci(n: int) -> int:
|
||
"""
|
||
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:
|
||
raise ValueError("Negative arguments are not supported")
|
||
return _fib(n)[0]
|
||
|
||
|
||
# returns (F(n), F(n-1))
|
||
def _fib(n: int) -> tuple[int, int]:
|
||
if n == 0: # (F(0), F(1))
|
||
return (0, 1)
|
||
|
||
# F(2n) = F(n)[2F(n+1) − F(n)]
|
||
# F(2n+1) = F(n+1)^2+F(n)^2
|
||
a, b = _fib(n // 2)
|
||
c = a * (b * 2 - a)
|
||
d = a * a + b * b
|
||
return (d, c + d) if n % 2 else (c, d)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
n = int(sys.argv[1])
|
||
print(f"fibonacci({n}) is {fibonacci(n)}")
|