12345678999(123억...)과 99987654321(999억...) 사이의 피보나치 수를 모두 더하면 얼마인가 에 대한 풀이를 해보았다. (원문 )
수의 범위가 매우 크기 때문에 루프 대신 generator를 사용했다. (루프로 코드를 짜보았지만 Quad Core에서도 오랜 시간 계산이 끝나지 않아서 포기했다)
import cProfile
import itertools
def Fibonacci_generator():
""" 피보나치 수를 구하는 generator """
yield 0
yield 1
prev1 = 0 # n-2
prev2 = 1 # n-1
result = 0
while True:
try:
result = prev1 + prev2
yield result
prev1 = prev2
prev2 = result
except OverflowError:
break
def solve(start, end):
""" star ~ end 사이의 피보나치 수의 합을 구하는 함수."""
total = 0L
for fib in Fibonacci_generator():
if fib >= end:
break
if fib > start:
total += fib
return total
def solve2(start, end):
""" star ~ end 사이의 피보나치 수의 합을 구하는 함수."""
return sum(itertools.takewhile(
lambda fib: fib < end,
itertools.dropwhile(lambda fib: fib > start,
Fibonacci_generator())))
start = 12345678999L
end = 99987654321L
cProfile.run('solve(%d, %d)' % (start, end))
print solve(start, end)
cProfile.run('solve2(%d, %d)' % (start, end))
print solve2(start, end)
결과는 아래와 같다.
$python fibo.py 60 function calls in 0.000 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 fibonachi.py:25(solve) 57 0.000 0.000 0.000 0.000 fibonachi.py:9(Fibonacci_generator) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 205486422643 118 function calls in 0.000 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 fibonachi.py:35(solve2) 6 0.000 0.000 0.000 0.000 fibonachi.py:37(<lambda>) 51 0.000 0.000 0.000 0.000 fibonachi.py:38(<lambda>) 57 0.000 0.000 0.000 0.000 fibonachi.py:9(Fibonacci_generator) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 0.000 0.000 0.000 0.000 {sum} 205486422643