#include <vector>
#include <stdexcept>
#include <algorithm>
template<class iterator_type>
class combination_generator {
iterator_type first, last;
std::vector<bool> use;
unsigned r;
typedef typename std::iterator_traits<iterator_type>::value_type element_type;
public:
combination_generator(iterator_type first_, iterator_type last_, unsigned r_) : first(first_), last(last_) , r(r_)
{
use.resize(std::distance(first, last), false);
if (r > use.size())
throw std::domain_error("can't select more elements than exist for combination");
std::fill(use.end()-r, use.end(), true);
}
template<class output_iterator>
bool operator()(output_iterator result)
{
iterator_type c=first;
for (unsigned i = 0; i<use.size(); ++i,++c) {
if (use[i])
*result++ = *c;
}
return std::next_permutation(use.begin(), use.end());
}
};
template<class iterator_type>
combination_generator<iterator_type> make_combination_generator(iterator_type first, iterator_type last, unsigned r)
{return combination_generator<iterator_type>(first, last, r);}
#include <string>
#include <iostream>
#include <iterator>
int main() {
std::string data[] = {"HELLO", "WORLD", "ALPHA", "BET"};
auto generator = make_combination_generator(data, data+4, 2);
std::ostream_iterator<std::string> it(std::cout, " ");
while(generator(it))
std::cout << '\n';
return 0;
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0ZGV4Y2VwdD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KCnRlbXBsYXRlPGNsYXNzIGl0ZXJhdG9yX3R5cGU+CmNsYXNzIGNvbWJpbmF0aW9uX2dlbmVyYXRvciB7CiAgICBpdGVyYXRvcl90eXBlIGZpcnN0LCBsYXN0OwogICAgc3RkOjp2ZWN0b3I8Ym9vbD4gdXNlOwogICAgdW5zaWduZWQgcjsKICAgIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjppdGVyYXRvcl90cmFpdHM8aXRlcmF0b3JfdHlwZT46OnZhbHVlX3R5cGUgZWxlbWVudF90eXBlOwpwdWJsaWM6CiAgICBjb21iaW5hdGlvbl9nZW5lcmF0b3IoaXRlcmF0b3JfdHlwZSBmaXJzdF8sIGl0ZXJhdG9yX3R5cGUgbGFzdF8sIHVuc2lnbmVkIHJfKSA6IGZpcnN0KGZpcnN0XyksIGxhc3QobGFzdF8pICwgcihyXykKICAgIHsKICAgICAgICB1c2UucmVzaXplKHN0ZDo6ZGlzdGFuY2UoZmlyc3QsIGxhc3QpLCBmYWxzZSk7CiAgICAgICAgaWYgKHIgPiB1c2Uuc2l6ZSgpKQogICAgICAgICAgICB0aHJvdyBzdGQ6OmRvbWFpbl9lcnJvcigiY2FuJ3Qgc2VsZWN0IG1vcmUgZWxlbWVudHMgdGhhbiBleGlzdCBmb3IgY29tYmluYXRpb24iKTsKICAgICAgICBzdGQ6OmZpbGwodXNlLmVuZCgpLXIsIHVzZS5lbmQoKSwgdHJ1ZSk7CiAgICB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBvdXRwdXRfaXRlcmF0b3I+CiAgICBib29sIG9wZXJhdG9yKCkob3V0cHV0X2l0ZXJhdG9yIHJlc3VsdCkgCiAgICB7CiAgICAgICAgaXRlcmF0b3JfdHlwZSBjPWZpcnN0OwogICAgICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGk8dXNlLnNpemUoKTsgKytpLCsrYykgewogICAgICAgICAgICBpZiAodXNlW2ldKSAKICAgICAgICAgICAgICAgICpyZXN1bHQrKyA9ICpjOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RkOjpuZXh0X3Blcm11dGF0aW9uKHVzZS5iZWdpbigpLCB1c2UuZW5kKCkpOwogICAgfQp9Owp0ZW1wbGF0ZTxjbGFzcyBpdGVyYXRvcl90eXBlPgpjb21iaW5hdGlvbl9nZW5lcmF0b3I8aXRlcmF0b3JfdHlwZT4gbWFrZV9jb21iaW5hdGlvbl9nZW5lcmF0b3IoaXRlcmF0b3JfdHlwZSBmaXJzdCwgaXRlcmF0b3JfdHlwZSBsYXN0LCB1bnNpZ25lZCByKQp7cmV0dXJuIGNvbWJpbmF0aW9uX2dlbmVyYXRvcjxpdGVyYXRvcl90eXBlPihmaXJzdCwgbGFzdCwgcik7fQoKI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aXRlcmF0b3I+CgppbnQgbWFpbigpIHsKICAgIHN0ZDo6c3RyaW5nIGRhdGFbXSA9IHsiSEVMTE8iLCAiV09STEQiLCAiQUxQSEEiLCAiQkVUIn07CiAgICBhdXRvIGdlbmVyYXRvciA9IG1ha2VfY29tYmluYXRpb25fZ2VuZXJhdG9yKGRhdGEsIGRhdGErNCwgMik7CiAgICBzdGQ6Om9zdHJlYW1faXRlcmF0b3I8c3RkOjpzdHJpbmc+IGl0KHN0ZDo6Y291dCwgIiAiKTsKICAgIHdoaWxlKGdlbmVyYXRvcihpdCkpIAogICAgICAgIHN0ZDo6Y291dCA8PCAnXG4nOwogICAgcmV0dXJuIDA7Cn0K