りおさんぶろぐ

問題25

プロジェクトオイラーの25問目。
初めて1000桁を超えるようなフィボナッチ数列の項数はいくつか、という問題。

(◎-ω-)。o○ (思案中)

  • 1000桁なんてCの貧弱ライブラリで耐えられません
  • フィボナッチ数列といえばヒマワリだよね(関係ない)
  • 加算は配列でやってみよう
  • 左右逆になるけど添字の小さい方からの実装が簡単だし、あとで逆順でprintすりゃ良い
int add1[1000] = {1};
int add2[1000] = {0};

void addi(void){
    int co = 0; int tmp;
    for(int i=0; i<1000; i++){
        tmp = add1[i] + add2[i] + co;
        add1[i] = add2[i];
        add2[i] = tmp%10;
        co = (tmp-add2[i])/10;
    }
}
  • coは桁上がり(名前は論理回路の加算器から拝借)
  • tmpはとりあえずの和の保存場所
  • add1+add2の体だけどadd2に和を詰めるよ(加算の前にadd2をadd1へコピーして次の準備)
  • 問題から、終了条件はadd2[999]!=0で良さそう

Cで実装

#include <stdio.h>
#include <stdlib.h>

int add1[1000] = {1};
int add2[1000] = {0};

void addi(void){
    int co = 0; int tmp;
    for(int i=0; i<1000; i++){
        tmp = add1[i] + add2[i] + co;
        add1[i] = add2[i];
        add2[i] = tmp%10;
        co = (tmp-add2[i])/10;
    }
}

void prtad(void){
    int i=999; while(add2[i]==0) i--;
    for(; i>=0; i--){
        printf("%d", add2[i]);
    }
}

int main(void){
    printf("--1000-digit Fibonacci number--\n");
    int i=0;
    while(1){
        addi(); i++;
        if(add2[999]!=0) break;
    }
    printf("F[%d] = ", i); prtad(); printf(".\n");
    return 0;
}

結果

$ gcc -Wall -std=c99 -o 25 25.c
$ ./25
--1000-digit Fibonacci number--
F[4782] = 1070066266382758936764980584457396885083683896632151665013235203375314520604694040621889147582489792657804694888177591957484336466672569959512996030461262748092482186144069433051234774442750273781753087579391666192149259186759553966422837148943113074699503439547001985432609723067290192870526447243726117715821825548491120525013201478612965931381792235559657452039506137551467837543229119602129934048260706175397706847068202895486902666185435124521900369480641357447470911707619766945691070098024393439617474103736912503231365532164773697023167755051595173518460579954919410967778373229665796581646513903488154256310184224190259846088000110186255550245493937113651657039447629584714548523425950428582425306083544435428212611008992863795048006894330309773217834864543113205765659868456288616808718693835297350643986297640660000723562917905207051164077614812491885830945940566688339109350944456576357666151619317753792891661581327159616877487983821820492520348473874384736771934512787029218636250627816.

‥せっかく1000桁表示したのにはてぶろに端折られた‥( ´ω` )
というわけで、第4782項らしい。ふーん‥

思ったけどstdlib.h使わへんな(スニペットで入れっぱなし)

気になるお時間は‥

real    0m0.349s
user    0m0.000s
sys     0m0.031s

意外と速い。

25問を解いて、ようやくれべる1になりました。
(22だけめんどくさそうで代わりに67を解いた)

次は50問、遠い‥_( _´ω`)_ペショ
気が向いたら他の問題も書こうかな