Project Euler 23

http://projecteuler.net/index.php?section=problems&id=23


まず28123以下の自然数の配列を作り、過剰数を求めて、それらの和に対し配列の値を0にして、最後に配列の和を取る。
iterableに対してproductがうまく動かなかったので、iterableを修正した。


itertools.h

#include <iostream>
#include "primes.h"

using namespace std;
using namespace itertools;

const int N = 28123;

int pow(int n, int e) {
    if(e == 0)
        return 1;
    
    int m = pow(n, e / 2);
    return e % 2 == 1 ? m * m * n : m * m;
}

bool is_abundant(int n) {
    using namespace primes;
    
    auto    f = factorize(n);
    return reduce1([] (int x, int y) { return x * y; },
            map([] (Fact f) -> int { int p = fst(f); int e = snd(f);
            return (pow(p, e + 1) - 1) / (p - 1); }, f)) > n * 2;
}

int main() {
    vector<int> a(N + 1);
    for(int k = 0; k <= N; k++)
        a[k] = k;
    
    auto    v = list(filter(is_abundant, range<>(2, N + 1)));
    auto    g = filter([] (int x) { return x <= N; },
                map([] (tuple<int,int> x) { return fst(x) + snd(x); },
                                                product(iterable(v))));
    while(g.exists_next()) {
        int n = g.next();
        a[n] = 0;
    }
    cout << sum(iterable(a)) << endl;
}