http://projecteuler.net/index.php?section=problems&id=4
Pythonでこう書くのを真似したい。
from itertools import ifilter, product def gen_digits(n): if n > 0: for d in gen_digits(n / 10): yield d yield n % 10 def to_number(a): return reduce(lambda x, y: x * 10 + y, a) def is_palindromic(n): return n == to_number(reversed(list(gen_digits(n)))) print reduce(max, ifilter(is_palindromic, (x * y for x, y in product(xrange(100, 1000), repeat = 2))))
こんなに短いコードでもかなり大変。
まずreduceを作る。
template<typename T, typename U> auto reduce(T f, U *g) -> decltype(f(g->next(), g->next())) { decltype(f(g->next(), g->next())) x = g->next(); try { while(true) x = f(x, g->next()); } catch(int e) { return x; } }
Pythonのreduceは型がいい加減。まだあまりよくできていない。
C++0xではここでラムダが使える。
return reduce([](int x, int y) { return x * 10 + y; }, g);
とりあえず、回文数の判定だけ。
#include <iostream> #include <vector> using namespace std; template<typename T> class cGenerator { public: virtual ~cGenerator() { } virtual T next() = 0; }; template<typename T, typename U> auto reduce(T f, U *g) -> decltype(f(g->next(), g->next())) { decltype(f(g->next(), g->next())) x = g->next(); try { while(true) x = f(x, g->next()); } catch(int e) { return x; } } template<typename T> auto list(T *g) -> vector<decltype(g->next())> { vector<decltype(g->next())> v; try { while(true) v.push_back(g->next()); } catch(int e) { return v; } } template<typename T> class reversed : public cGenerator<T> { vector<T>& v; int k; public: reversed(vector<T>& v) : v(v) { k = (int)v.size() - 1; } T next() { if(k == -1) throw(1); return v[k--]; } }; template<typename T> class digits : cGenerator<T> { int d; digits<T> *g; public: digits(int n) { g = NULL; if(n > 0) g = new digits(n / 10); d = n % 10; } int next() { if(g != NULL) { try { return g->next(); } catch(int e) { g = NULL; return d; } } throw(1); } }; template<typename T> T to_numerize(cGenerator<T> *g) { return reduce([](int x, int y) { return x * 10 + y; }, g); } template<typename T> bool is_palindromic(T n) { return n == to_numerize(new reversed<int>(list(new digits<T>(n)))); } int main() { cout << is_palindromic(123) << endl; cout << is_palindromic(121) << endl; }