Project Euler 36

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


10進の回文数再帰的に生成して、それが2進で回文になっているかを調べる。

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

using namespace std;
using namespace itertools;

int pow(int n, int e) {
    return e == 0 ? 1 : n * pow(n, e - 1);
}

class cPalindromic {
    cPalindromic    *pali;
    const int   num;
    const int   d;
    int         current;
    int         k;
    const bool  rec_call;
    
public:
    cPalindromic(int m, bool r = false) : num(m), rec_call(r),
                        k(0), d(m == 1 ? 1 : (pow(10, m - 1) + 1)) {
        current = -1;
        if(num > 2)
            pali = new cPalindromic(num - 2, true);
    }
    cPalindromic(const cPalindromic& p) : num(p.num), k(p.k),
                    rec_call(p.rec_call), d(p.d), current(p.current) {
        if(num > 2)
            pali = new cPalindromic(num - 2, true);
    }
    ~cPalindromic() {
        if(num > 2)
            delete pali;
    }
    int next() {
        if(rec_call) {
            if(num > 2)
                current = k == 0 ? pali->next() * 10 : current + d;
            else
                current = k == 0 ? 0 : current + d;
            k = k == 9 ? 0 : k + 1;
        }
        else {
            if(num > 2)
                current = k == 0 ? pali->next() * 10 + d : current + d;
            else
                current = k == 0 ? d : current + d;
            k = k == 8 ? 0 : k + 1;
        }
        return current;
    }
    bool exists_next() {
        if(num > 2)
            return k != 0 || pali->exists_next();
        else
            return k != 0 || current == -1;
    }
};

bool is_palindromic2(int n) {
    return n == reduce1([] (int x, int y) { return x * 2 + y; },
                    digits<int,2>(n));
}

int main() {
    const int   N = 6;
    cout << sum(map([] (int n)
            { return sum(filter(is_palindromic2, cPalindromic(n))); },
            range<>(1, N + 1))) << endl;
}