#pragma once #include #include #include template V select(const V &options, const std::vector &mask, size_t count) { V result; result.reserve(count); for (int i = 0; i < mask.size(); ++i) { if (mask[i]) result.push_back(options[i]); } return result; } template std::set combinations(const V &options, size_t count) { std::set result; std::vector mask(options.size(), false); std::fill(mask.begin(), mask.begin() + count, true); do { result.insert(select(options, mask, count)); } while (std::next_permutation(mask.begin(), mask.end(), std::greater<>())); return result; } template std::set set_difference(const std::set &a, const std::set &b) { std::set result; std::set_difference( a.begin(), a.end(), b.begin(), b.end(), std::inserter(result, result.end()) ); return result; } template std::set set_union(const std::set &a, const std::set &b) { std::set result; std::set_union( a.begin(), a.end(), b.begin(), b.end(), std::inserter(result, result.end()) ); return result; }