Project Euler 24

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


この問題は本来順列を出す必要はないが、後々のために順列を出すクラスを作った。この問題の答えは出るが、あまりうまく動かない。


itertools.h

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

using namespace std;
using namespace itertools;

template<typename T>
ostream& operator <<(ostream& os, const vector<T>& v) {
    for(int k = 0; k < (int)v.size(); k++)
        os << v[k];
    return os;
}

template<typename T>
class cPerm {
    typename std::vector<T>::iterator   begin;
    typename std::vector<T>::iterator   end;
    int     k;
    cPerm   *perm;
    
public:
    cPerm(typename vector<T>::iterator b,
                typename vector<T>::iterator e) :
                                begin(b), end(e), k(0) {
        if(begin != end)
            perm = new cPerm(begin + 1, end);
    }
    cPerm(const cPerm& p) :
                begin(p.begin), end(p.end), k(p.k) {
        if(begin != end)
            perm = new cPerm(begin + 1, end);
    }
    ~cPerm() {
        if(begin != end)
            delete perm;
    }
    void next() {
        if(perm->exists_next()) {
            perm->next();
        }
        else {
            k++;
            reverse(begin + 1, end);
            T   tmp = *begin;
            *begin = *(begin + k);
            *(begin + k) = tmp;
            delete perm;
            perm = new cPerm(begin + 1, end);
        }
    }
    bool exists_next() {
        if(begin != end)
            return k != end - begin - 1 || perm->exists_next();
        else
            return false;
    }
};

template<typename T>
class cPermutation {
    typename std::vector<T>::iterator   begin;
    typename std::vector<T>::iterator   end;
    vector<T>   ret;
    cPerm<T>    *perm;
    int         length;
    bool        first;
    
public:
    cPermutation(std::vector<T>& v) : begin(v.begin()),
                        end(v.end()), length(v.size()), first(true) {
        ret = vector<T>(length);
        perm = new cPerm<T>(begin, end);
    }
    cPermutation(const cPermutation& p) : begin(p.begin),
                end(p.end), length(p.length), ret(p.ret), first(true) {
        perm = new cPerm<T>(begin, end);
    }
    ~cPermutation() { delete perm; }
    cPermutation& operator =(const cPermutation& p) {
        begin = p.begin;
        end = p.end;
        ret = p.ret;
        length = p.length;
        perm = new cPerm<T>(begin, end);
        first = p.first;
        return *this;
    }
    vector<T> next() {
        if(!first)
            perm->next();
        first = false;
        for(int k = 0; k < length; k++)
            ret[k] = *(begin + k);
        return ret;
    }
    bool exists_next() { return perm->exists_next(); }
};

template<typename T>
cPermutation<T> permutation(vector<T>& v) {
    return cPermutation<T>(v);
}

int main() {
    const int   N = (int)1e6;
    vector<int> v = list(range<>(10));
    cout << snd(head(filter([N] (tuple<int,vector<int>> x)
                { return fst(x) == N; },
                zip(itertools::count<>(1), permutation(v))))) << endl;
}