Non brute force solution to Project Euler problem 25

2024/10/7 22:23:13

Project Euler problem 25:

The Fibonacci sequence is defined by the recurrence relation:

Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1. Hence the first 12 terms will be F1 = 1, F2 = 1, F3 = 2, F4 = 3, F5 = 5, F6 = 8, F7 = 13, F8 = 21, F9 = 34, F10 = 55, F11 = 89, F12 = 144

The 12th term, F12, is the first term to contain three digits.

What is the first term in the Fibonacci sequence to contain 1000 digits?

I made a brute force solution in Python but it takes forever. Can anyone suggest a non brute force solution?

def Fibonacci(NthTerm):if NthTerm == 1 or NthTerm == 2:return 1 # Challenge defines 1st and 2nd term as == 1else:  # recursive definition of Fib termreturn Fibonacci(NthTerm-1) + Fibonacci(NthTerm-2)FirstTerm = 0 # For scope to include Term in scope of print on line 13
for Term in range(1, 1000): # Arbitrary rangeFibValue = str(Fibonacci(Term)) # Convert integer to string for len()if len(FibValue) == 1000:FirstTerm = Termbreak # Stop thereelse:continue # Go to next number
print "The first term in the\nFibonacci sequence to\ncontain 1000 digits\nis the", FirstTerm, "term."
Answer

You can write a fibonacci function that runs in linear time and with constant memory footprint, you don't need a list to keep them. Here's a recursive version (however, if n is big enough, it will just stackoverflow)

def fib(a, b, n):if n == 1:return aelse: return fib(a+b, a, n-1)print fib(1, 0, 10) # prints 55

This function calls itself only once (resulting in around N calls for a parameter N), in contrast with your solution which calls itself twice (around 2^N calls for a parameter N).

Here's a version that won't ever stackoverflow and uses a loop instead of recursion:

def fib(n):a = 1b = 0while n > 1:a, b = a+b, an = n - 1return aprint fib(100000)

And that's fast enough:

$ time python fibo.py 
3364476487643178326662161200510754331030214846068006390656476...real    0m0.869s

But calling fib until you get a result big enough isn't perfect: the first numbers of the serie are calculated multiple times. You can calculate the next fibonacci number and check its size in the same loop:

a = 1
b = 0
n = 1
while len(str(a)) != 1000:a, b = a+b, an = n + 1
print "%d has 1000 digits, n = %d" % (a, n)
https://en.xdnf.cn/q/70196.html

Related Q&A

python:class attribute/variable inheritance with polymorphism?

In my endeavours as a python-apprentice i got recently stuck at some odd (from my point of view) behaviour if i tried to work with class attributes. Im not complaining, but would appreciate some helpfu…

Unable to load firefox in selenium webdriver in python

I have installed Python 3.6.2, Selenium 3.5.0 with GeckoDriver 0.18.0 and the firefox version is 54.0.1version on windows 7. I am trying to run a selenium script which is loading a firefox where i get …

Plot hyperplane Linear SVM python

I am trying to plot the hyperplane for the model I trained with LinearSVC and sklearn. Note that I am working with natural languages; before fitting the model I extracted features with CountVectorizer …

Calculating plugin dependencies

I have the need to create a plugin system that will have dependency support and Im not sure the best way to account for dependencies. The plugins will all be subclassed from a base class, each with i…

Vectorization: Not a valid collection

I wanna vectorize a txt file containing my training corpus for the OneClassSVM classifier. For that Im using CountVectorizer from the scikit-learn library. Heres below my code: def file_to_corpse(file…

Solve a simple packing combination with dependencies

This is not a homework question, but something that came up from a project I am working on. The picture above is a packing configuration of a set of boxes, where A,B,C,D is on the first layer and E,F,G…

ImportError: cannot import name FFProbe

I cant get the ffprobe package to work in Python 3.6. I installed it using pip, but when I type import ffprobe it saysTraceback (most recent call last): File "<stdin>", line 1, in <m…

Generate larger synthetic dataset based on a smaller dataset in Python

I have a dataset with 21000 rows (data samples) and 102 columns (features). I would like to have a larger synthetic dataset generated based on the current dataset, say with 100000 rows, so I can use it…

Executing python script in android terminal emulator

I installed python 2.7 in my Android device and I tried executing a python script by typing the command in terminal emulator. The problem is that although I use the full path for python the following e…

How to return error messages in JSON with Bottle HTTPError?

I have a bottle server that returns HTTPErrors as such:return HTTPError(400, "Object already exists with that name")When I receive this response in the browser, Id like to be able to pick out…