ヨーキョクデイ

いろいろ雑食

foreach 用フィボナッチ数列生成器

これがいい。

import std.stdio;

class Fibonacci(T){
    private T current;
    private T next;
    private bool isFirstTime;
    private bool useCountLimit;
    private size_t countLimit;

    this(T first, T second){
        current = first;
        next = second;
        isFirstTime = true;
    }
    this(T first, T second, size_t countlimit){
        this(first, second);
        useCountLimit = true;
        countLimit = countlimit;
    }

    private void forward(){
        if(isFirstTime){
            isFirstTime = false;
        }
        else{
            auto tmp = next + current;
            current = next;
            next = tmp;
        }
    }

    int opApply(int delegate(ref T) dg){
        int result;
        for(size_t i; useCountLimit ? i < countLimit : 1; useCountLimit ? i++ : 0){
            forward();
            auto k = current;
            result = dg(k);
            if(result){
                break;
            }
        }
        return result;
    }
    int opApply(int delegate(ref size_t, ref T) dg){
        int result;
        for(size_t i; useCountLimit ? i < countLimit : 1; i++){
            forward();
            auto k = current;
            result = dg(i, k);
            if(result){
                break;
            }
        }
        return result;
    }
}


void main(){
    auto fib = new Fibonacci!(uint)(0, 1);  // 無限 foreach
    // M 以下の値である項の総和を求めたい
    const uint M = 20;
    uint sum;
    foreach(k; fib){
        if(k > M){
            break;
        }
        sum += k;
    }
    writeln("Sum[i,fib(i)<=M] = ", sum);

    writeln();

    const uint N = 15;
    auto fib2 = new Fibonacci!(uint)(0, 1, N);  // 有限 foreach(N 回)
    // 最初の N 項を列挙したい
    foreach(i, k; fib2){
        writefln("fib(%d) = %d", i, k);
    }

}

foreach に渡すことしか考えていないクラスにした。
これを実行した結果。

Sum[i,fib(i)<=M] = 33

fib(0) = 0
fib(1) = 1
fib(2) = 1
fib(3) = 2
fib(4) = 3
fib(5) = 5
fib(6) = 8
fib(7) = 13
fib(8) = 21
fib(9) = 34
fib(10) = 55
fib(11) = 89
fib(12) = 144
fib(13) = 233
fib(14) = 377