http://projecteuler.net/index.php?section=problems&id=49
重複組合せを出し、それぞれについて順列を出し、その中の2つずつを取って等差数列を作って次の口が順列にあるか調べて、あればそれぞれ素数か調べる。
#include <iostream> #include "primes.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 cRepeatedCombination { const vector<T> vmap; vector<T> ret; vector<int> ref; int length; bool first; public: cRepeatedCombination(const vector<T>& v, int n) : vmap(v), length(n) { ret = vector<int>(length, v.front()); ref = vector<int>(length, 0); first = true; } vector<T> next() { if(!first) { const int p = pos(length - 1); ref[p]++; ret[p] = vmap[ref[p]]; reset(ref[p], p + 1); } first = false; return ret; } bool exists_next() { return exists(); } private: int pos(int p) { if(ref[p] != vmap.size() - 1) return p; else return pos(p - 1); } void reset(int n, int p) { if(p == length) return; ref[p] = n; ret[p] = vmap[n]; reset(n, p + 1); } bool exists(int p = 0) { if(p == length) return false; else if(ref[p] != vmap.size() - 1) return true; else return exists(p + 1); } }; template<typename T> cRepeatedCombination<T> repeated_combination(const vector<T>& v, int n) { return cRepeatedCombination<T>(v, n); } const int N = 4; const int M = 1000; void diff_primes(vector<int> v) { using namespace primes; set<int> s; auto g = perm(v); while(g.exists_next()) { int n = to_number(iterable(g.next())); if(n >= M) s.insert(n); } for(auto p = s.begin(); p != s.end(); ++p) { int n1 = *p; if(!is_prime(n1)) continue; for(auto q = s.begin(); q != s.end(); ++q) { int n2 = *q; int n3 = n2 * 2 - n1; if(n1 < n2 && s.find(n3) != s.end() && is_prime(n2) && is_prime(n3)) cout << n1 << n2 << n3 << endl; } } } int main() { auto rc = repeated_combination(list(range<>(10)), N); iter(diff_primes, rc); }