前回は、Project Euler で紹介されている問題25を解いてみました。前回は、フィボナッチ数列の定義に従い計算をしましたが、今回は、一般項を求めて計算します。
再掲載 Project Euler 問題25(1000桁のフィボナッチ数)
フィボナッチ数列は、次の漸化式で定義される。
したがって、最初の12項は次となる。
第12項
フィボナッチ数列は、何項目で1000桁になるか求めよ。
考察
フィボナッチ数列の漸化式は、以下となります。
フィボナッチ数列の一般項
一般項の2番目の項は、
近似式のように見えますが、右辺の式を整数単位で切り上げれば正確な値になります。
この式の両辺の
一般的に
解答例
一般項から、直接
"""Project Euler Problem025"""
import math
N = 999
sqrt5 = math.sqrt(5.0)
answer = math.ceil((N + math.log10(sqrt5))/math.log10((1.0 + sqrt5)/2.0))
print("Problem025: " + str(answer))
2行目で桁数を変更できます。
C では、以下となります。値を大きくできるように関係する変数は long long int 型にしました。math.h を使っているため、コンパイル時(リンク時)に、「-lm」オプションが必要となります。またオンライン実行環境では、コンパイルできない環境があるかもしれません(過去に紹介した paiza.iO では動作しました)。
#include <stdio.h>
#include <math.h>
int main(void)
{
long long int n = 999;
long long int term;
double sqrt5;
sqrt5 = sqrt(5.0);
term = (long long int)ceil(((double)n + log10(sqrt5))/log10((1.0 + sqrt5)/2.0));
printf("Problem025: %lld\n", term);
return 0;
}
C 版も6行目で桁数を変更できます。
結果を振り返る
前回は、問題の1000桁を増やしていきました。100万桁を超えると計算量が大きくなり計算をあきらめました。今回は、計算量が一定です。追加で結果を記します。
X 桁 | X 桁になる最初の項 |
10000(104) | 47847 |
100000(105) | 478495 |
1000000(106) | 4784969 |
10000000(107) | 47849717 |
100000000(108) | 478497194 |
1000000000(109) | 4784971964 |
求めた式を近似値で記すと以下となります。
不等式の係数は複雑ですが一次式です。そのため、X が10倍になれば、それを超えるフィボナッチ数列の項も10倍になります。
倍精度の浮動小数点は、10進数で15桁ほどの精度を持ちます。その程度までは、この式で正確な項数を求めることができます。
最後に
フィボナッチ数列の一般項を求めるのは、高校数学の履修範囲となっています(数学B「数列」)。この知識を使って、問題の計算量を
今回で、当初の目標であった Project Euler の最初の25問を解くことができました。この25問の難易度を振り返ります。