http://projecteuler.net/index.php?section=problems&id=28
スパイラルの座標を次々に出すクラスを作った。
#include <iostream> #include "itertools.h" using namespace std; using namespace itertools; typedef tuple<int,int> Point; class cSpiral { Point pt; public: cSpiral() : pt(make_tuple(0, 0)) { } Point next() { Point prev_pt = pt; int x = fst(pt); int y = snd(pt); if(y >= 0 && -y <= x && x <= y) pt = make_tuple(x + 1, y); else if(x > 0 && y > -x) pt = make_tuple(x, y - 1); else if(y < 0 && x > y) pt = make_tuple(x - 1, y); else pt = make_tuple(x, y + 1); return prev_pt; } bool exists_next() { return true; } }; bool is_on_diagonal(Point pt) { return abs(fst(pt)) == abs(snd(pt)); } int main() { const int N = 1001; typedef tuple<int,Point> Comb; cout << sum(takewhile([N] (int n) { return n <= N * N; }, map(fst<int,Point>, filter([] (Comb x) { return is_on_diagonal(snd(x)); }, zip(itertools::count<>(1), cSpiral()))))) << endl; }