http://projecteuler.net/index.php?section=problems&id=50
unfoldを作ってみた。
#include <iostream> #include "primes.h" using namespace std; using namespace itertools; const int N = 1000000; template<typename T, typename U, typename V> class cUnfold { T& fun; U stat; public: cUnfold(T& f, U init) : fun(f), stat(init) { } V next() { auto x = fun(stat); stat = snd(x); return fst(x); } bool exists_next() { return true; } }; template<typename T, typename U> auto unfold(T& f, U init) -> cUnfold<T,U,decltype(fst(f(init)))> { return cUnfold<T,U,decltype(fst(f(init)))>(f, init); } typedef tuple<int,int> t_int; // 最も長い和が素数になる素数列 t_int base_length(int k) { auto ps = primes::genPrimes(); for(int i = 0; i < k; i++) ps.next(); auto g = unfold([&ps] (int s) -> t_int { int s1 = s + ps.next(); return t_int(s1, s1); }, 0); vector<int> v = list(takewhile([] (int n) { return n < N; },g)); int n = fst(last(filter([] (t_int t) { return primes::is_prime(snd(t)); }, zip(itertools::count<>(1), iterable(v))))); return t_int(v.size(), n); } int sum_max_length(int k, int L) { auto ps = primes::genPrimes(); for(int i = 0; i < k; i++) ps.next(); return sum(map(snd<int,int>, (takewhile([L] (t_int t) { return fst(t) <= L; }, zip(itertools::count<>(1), ps))))); } int main() { int max_k = -1; int max_length = 0; for(int k = 0; k < 10; k++) { t_int x = base_length(k); if(snd(x) > max_length) { max_length = snd(x); max_k = k; } if(fst(x) < max_length) { cout << sum_max_length(max_k, max_length) << endl; break; } } }