mirror of https://github.com/exaloop/codon.git
95 lines
2.4 KiB
C++
95 lines
2.4 KiB
C++
#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;
|
|
}
|