📝 docs(solutions):添加排列问题README文档说明欧拉数算法 ♻️ refactor(solutions):重构排列问题代码,添加数学计算方法 ✨ feat(solutions):新增斐波那契问题解决方案,支持大数计算和Binet公式 🔧 chore(solutions):为两个解决方案添加性能计时器装饰器
78 lines
2.0 KiB
Python
78 lines
2.0 KiB
Python
"""
|
|
The Fibonacci sequence is defined by the recurrence relation:
|
|
F_n = F_{n-1} + F_{n-2}, where F_1 = 1 and F_2 = 1.
|
|
|
|
Hence the first 12 terms will be: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144
|
|
The 12th term, F_12, is the first term to contain three digits.
|
|
|
|
What is the index of the first term in the Fibonacci sequence to contain 1000-digits?
|
|
"""
|
|
|
|
import math
|
|
import time
|
|
|
|
|
|
def timer(func):
|
|
def wrapper(*args, **kwargs):
|
|
start_time = time.time()
|
|
result = func(*args, **kwargs)
|
|
end_time = time.time()
|
|
during = end_time - start_time
|
|
if during > 1:
|
|
print(f"function {func.__name__} taken: {during:.6f} seconds")
|
|
elif during > 0.001:
|
|
print(f"function {func.__name__} taken: {during * 1000:.3f} milliseconds")
|
|
else:
|
|
print(
|
|
f"function {func.__name__} taken: {during * 1000000:.3f} microseconds"
|
|
)
|
|
return result
|
|
|
|
return wrapper
|
|
|
|
|
|
def big_sum(a: str, b: str) -> str:
|
|
length = max(len(a), len(b))
|
|
carry = 0
|
|
result = []
|
|
for i in range(length):
|
|
digit_a = int(a[-i - 1]) if i < len(a) else 0
|
|
digit_b = int(b[-i - 1]) if i < len(b) else 0
|
|
sum_digit = digit_a + digit_b + carry
|
|
result.append(str(sum_digit % 10))
|
|
carry = sum_digit // 10
|
|
if carry:
|
|
result.append(str(carry))
|
|
return "".join(result[::-1])
|
|
|
|
|
|
def find_fibonacci_index(digits: int) -> int:
|
|
a, b = "1", "1"
|
|
index = 1
|
|
while len(a) < digits:
|
|
a, b = b, big_sum(a, b)
|
|
index += 1
|
|
return index
|
|
|
|
|
|
@timer
|
|
def main_in_bigint():
|
|
print(find_fibonacci_index(1000))
|
|
|
|
|
|
def binet(n: int) -> int:
|
|
index = math.ceil(
|
|
(math.log10(math.sqrt(5)) + (n - 1)) / math.log10(0.5 * (1 + math.sqrt(5)))
|
|
)
|
|
return index
|
|
|
|
|
|
@timer
|
|
def main_use_binet():
|
|
print(f"{binet(1000)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main_in_bigint()
|
|
main_use_binet()
|