http://projecteuler.net/index.php?section=problems&id=43
最後に頭に数字をつけるところは、45からその数の各桁の合計を引けばよい。
#include <iostream> #include "itertools.h" using namespace std; using namespace itertools; const int primes_rev[] = { 17, 13, 11, 7, 5, 3, 2 }; bool is_pandigital(int n, int m) { int f = 0; for(int k = 0; k < m; k++) { int d = n % 10; if(f & (1 << d)) return false; f |= 1 << d; n /= 10; } return true; } int pow(int n, int e) { return e == 0 ? 1 : n * pow(n, e - 1); } vector<int> next_pan(vector<int>& v0, int k) { int p = primes_rev[k]; int m = pow(10, k); int m2 = m * 100; return list(filter([&] (int n) { return n / m % p == 0 && is_pandigital(n, k + 3); }, map([&] (tuple<int,int> x) { return fst(x) * m2 + snd(x); }, product(range<>(10), iterable(v0))))); } long long complement(int n) { int d = 45 - sum(digits(n)); return d * (long long)pow(10, 9) + n; } int main() { auto g = filter([] (int n) { return is_pandigital(n, 3); }, range<>(17, 1000, 17)); auto v = reduce(next_pan, range<>(1, 7), list(g)); cout << sum(map(complement, iterable(v))) << endl; }