Saturday, July 25, 2009

Grind Report 25

Problem 25

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:

F_(1) = 1
F_(2) = 1
F_(3) = 2
F_(4) = 3
F_(5) = 5
F_(6) = 8
F_(7) = 13
F_(8) = 21
F_(9) = 34
F_(10) = 55
F_(11) = 89
F_(12) = 144

The 12th term, F_(12), is the first term to contain three digits.

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


*WARNING: This contains the solution!*

1000 digits, eh? That's a lot of digits. And once again there are two ways to solve this. Brute force or some method paved with gold. Amazingly I went with brute force this time since it was the one that required programming, but I'll go over the gold way as well.

My brute force method is kind of cheating but it is smart cheating? This raises the moral issue of whether cheating is acceptable as long as it is done in an intelligent manner. Anyways, the way I cheated is that while calculating Fibonacci numbers to find the first one with 1000 digits, instead of keeping all of the digits, which would be impossible with built in types, I just would cut off the less significant digits when the number got to a certain size and keep count of how many digits I cut off. This method worked like a charm and the algorithm is very fast! :)

The golden method is real gold! If you ever took calculus with Mr. Penner at Red Bluff High School, then you would know what the golden ratio is - (1 + sqrt(5)) / 2. You would also know that Fn/Fn-1 converges to this golden ratio, which is known as phi. Taking this golden ratio and using it with the fact that if you take the ceil(log10(n)) then you will actually the number of digits that number contains, we can solve this problem by hand (preferably with a calculator in it). This looks something like...

ceil(((999 + log10(sqrt(5)))/log10((1 + sqrt(5))/2))

Yay! Math!

Oh, yeah. Here is my brute force goodness.

#include <iostream>
#include <math.h>

int main()
{
long long f = 1;
long long fn = 1;
int count = 0;
int i = 2;
while (count + (int)ceil(log10((long double)fn)) < 1000)
{
long long temp = fn;
fn += f;
f = temp;
if (fn > 1000000000000)
{
fn /= 10;
f /= 10;
++count;
}
++i;
}
std::cout << i;
}

*saved game*

No comments:

Post a Comment