#include <algorithm> #include <chrono> #include <functional> #include <iostream> #include <vector> template <class T> using vec = std::vector<T>; inline vec<int> range(int start, int stop) { vec<int> v(stop - start); uint j = 0; for (int i = start; i < stop; i++) v[j++] = i; return v; } inline bool conforms(const vec<vec<int>> &candidate, int minsize, int forgive) { int deficit = 0; for (const auto &p : candidate) { int need = minsize - static_cast<int>(p.size()); if (need > 0) deficit += need; } return deficit <= forgive; } inline void partition_filtered(const vec<int> &collection, std::function<void(const vec<vec<int>> &)> callback, int minsize = 1, int forgive = 0) { if (collection.size() == 1) { callback({collection}); return; } auto first = collection[0]; auto loop = [&](const vec<vec<int>> &smaller) { int n = 0; vec<vec<int>> candidate; candidate.reserve(smaller.size() + 1); vec<int> rep; for (const auto &subset : smaller) { candidate.resize(n); for (int i = 0; i < n; i++) candidate[i] = smaller[i]; rep.clear(); rep.reserve(subset.size() + 1); rep.push_back(first); rep.insert(rep.end(), subset.begin(), subset.end()); candidate.push_back({rep}); for (int i = n + 1; i < smaller.size(); i++) candidate.push_back(smaller[i]); if (conforms(candidate, minsize, forgive)) callback(candidate); ++n; } candidate.clear(); candidate.push_back({first}); candidate.insert(candidate.end(), smaller.begin(), smaller.end()); if (conforms(candidate, minsize, forgive)) callback(candidate); }; vec<int> new_collection(collection.begin() + 1, collection.end()); partition_filtered(new_collection, loop, minsize, forgive + 1); } int main(int argc, char *argv[]) { using clock = std::chrono::high_resolution_clock; using std::chrono::duration_cast; using std::chrono::milliseconds; auto t = clock::now(); int n = 1; int x = 0; auto callback = [&](const vec<vec<int>> &p) { auto copy = p; std::sort(copy.begin(), copy.end()); x += copy[copy.size() / 3][0]; }; auto something = range(1, std::atoi(argv[1])); partition_filtered(something, callback, 2); std::cout << x << std::endl; std::cout << (duration_cast<milliseconds>(clock::now() - t).count() / 1e3) << std::endl; }