// Generate successive k-length permutations from sequence. (2.00)
// (eliminates indirect indexing)
// @see hHkYMq
#include <algorithm>
#include <vector>
#include <iostream>
template<typename T>
struct Permutation {
template<typename InputIt>
Permutation(InputIt, InputIt, int k);
bool next();
std::vector<T> get() const;
private:
std::vector<T> m_pool;
std::vector<int> m_cycle;
};
template<typename T>
template<typename InputIt>
Permutation<T>::Permutation(InputIt first, InputIt last, int k)
: m_pool(first, last)
{
int n = m_pool.size();
k = std::min(k, n);
for (int i = 0; i < k; i++)
m_cycle.push_back(n-i);
}
template<typename T>
bool Permutation<T>::next()
{
int n = m_pool.size();
for (int k = m_cycle.size(), i = k-1; i >= 0; i--)
{
if (--m_cycle[i])
{
std::swap(m_pool[i], m_pool[n - m_cycle[i]]);
return true;
}
m_cycle[i] = n - i;
auto first = m_pool.begin();
std::rotate(std::next(first, i), std::next(first, i+1), m_pool.end());
}
return false;
}
template<typename T>
std::vector<T> Permutation<T>::get() const
{
auto first = m_pool.begin();
return std::vector<T>(first, std::next(first, m_cycle.size()));
}
template<typename InputIt>
auto make_permutation(InputIt first, InputIt last, int k)
{
typedef typename std::iterator_traits<InputIt>::value_type value_type;
return Permutation<value_type>(first, last, k);
}
template<typename InputIt>
auto make_permutation(InputIt first, InputIt last)
{
return make_permutation(first, last, std::distance(first, last));
}
//
// Main.
//
template<typename T>
void show(Permutation<T>&& permutation)
{
do
{
for (auto x : permutation.get())
std::cout << x;
std::cout << ' ';
}
while (permutation.next());
std::cout << std::endl;
}
int main()
{
// Expect: AB AC AD BA BC BD CA CB CD DA DB DC
std::string s{"ABCD"};
show(make_permutation(s.begin(), s.end(), 2));
// Expect: 012 021 102 120 201 210
std::vector<int> v{0, 1, 2};
show(make_permutation(v.begin(), v.end()));
}
Ly8gR2VuZXJhdGUgc3VjY2Vzc2l2ZSBrLWxlbmd0aCBwZXJtdXRhdGlvbnMgZnJvbSBzZXF1ZW5jZS4gKDIuMDApCi8vIChlbGltaW5hdGVzIGluZGlyZWN0IGluZGV4aW5nKQovLyBAc2VlIGhIa1lNcQoKI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IFBlcm11dGF0aW9uIHsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIElucHV0SXQ+CiAgICBQZXJtdXRhdGlvbihJbnB1dEl0LCBJbnB1dEl0LCBpbnQgayk7CiAgICBib29sIG5leHQoKTsKICAgIHN0ZDo6dmVjdG9yPFQ+IGdldCgpIGNvbnN0OwoKcHJpdmF0ZToKICAgIHN0ZDo6dmVjdG9yPFQ+IG1fcG9vbDsKICAgIHN0ZDo6dmVjdG9yPGludD4gbV9jeWNsZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnRlbXBsYXRlPHR5cGVuYW1lIElucHV0SXQ+ClBlcm11dGF0aW9uPFQ+OjpQZXJtdXRhdGlvbihJbnB1dEl0IGZpcnN0LCBJbnB1dEl0IGxhc3QsIGludCBrKQo6IG1fcG9vbChmaXJzdCwgbGFzdCkKewogICAgaW50IG4gPSBtX3Bvb2wuc2l6ZSgpOwogICAgayA9IHN0ZDo6bWluKGssIG4pOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBrOyBpKyspCiAgICAgICAgbV9jeWNsZS5wdXNoX2JhY2sobi1pKTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KYm9vbCBQZXJtdXRhdGlvbjxUPjo6bmV4dCgpCnsKICAgIGludCBuID0gbV9wb29sLnNpemUoKTsKICAgIGZvciAoaW50IGsgPSBtX2N5Y2xlLnNpemUoKSwgaSA9IGstMTsgaSA+PSAwOyBpLS0pCiAgICB7CiAgICAgICAgaWYgKC0tbV9jeWNsZVtpXSkKICAgICAgICB7CiAgICAgICAgICAgIHN0ZDo6c3dhcChtX3Bvb2xbaV0sIG1fcG9vbFtuIC0gbV9jeWNsZVtpXV0pOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgbV9jeWNsZVtpXSA9IG4gLSBpOwogICAgICAgIGF1dG8gZmlyc3QgPSBtX3Bvb2wuYmVnaW4oKTsKICAgICAgICBzdGQ6OnJvdGF0ZShzdGQ6Om5leHQoZmlyc3QsIGkpLCBzdGQ6Om5leHQoZmlyc3QsIGkrMSksIG1fcG9vbC5lbmQoKSk7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0ZDo6dmVjdG9yPFQ+IFBlcm11dGF0aW9uPFQ+OjpnZXQoKSBjb25zdAp7CiAgICBhdXRvIGZpcnN0ID0gbV9wb29sLmJlZ2luKCk7CiAgICByZXR1cm4gc3RkOjp2ZWN0b3I8VD4oZmlyc3QsIHN0ZDo6bmV4dChmaXJzdCwgbV9jeWNsZS5zaXplKCkpKTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgSW5wdXRJdD4KYXV0byBtYWtlX3Blcm11dGF0aW9uKElucHV0SXQgZmlyc3QsIElucHV0SXQgbGFzdCwgaW50IGspCnsKICAgIHR5cGVkZWYgdHlwZW5hbWUgc3RkOjppdGVyYXRvcl90cmFpdHM8SW5wdXRJdD46OnZhbHVlX3R5cGUgdmFsdWVfdHlwZTsKICAgIHJldHVybiBQZXJtdXRhdGlvbjx2YWx1ZV90eXBlPihmaXJzdCwgbGFzdCwgayk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIElucHV0SXQ+CmF1dG8gbWFrZV9wZXJtdXRhdGlvbihJbnB1dEl0IGZpcnN0LCBJbnB1dEl0IGxhc3QpCnsKICAgIHJldHVybiBtYWtlX3Blcm11dGF0aW9uKGZpcnN0LCBsYXN0LCBzdGQ6OmRpc3RhbmNlKGZpcnN0LCBsYXN0KSk7Cn0KCi8vCi8vIE1haW4uCi8vCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIHNob3coUGVybXV0YXRpb248VD4mJiBwZXJtdXRhdGlvbikKewogICAgZG8KICAgIHsKICAgICAgICBmb3IgKGF1dG8geCA6IHBlcm11dGF0aW9uLmdldCgpKQogICAgICAgICAgICBzdGQ6OmNvdXQgPDwgeDsKICAgICAgICBzdGQ6OmNvdXQgPDwgJyAnOwogICAgfQogICAgd2hpbGUgKHBlcm11dGF0aW9uLm5leHQoKSk7CiAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwp9CgppbnQgbWFpbigpCnsKICAgIC8vIEV4cGVjdDogQUIgQUMgQUQgQkEgQkMgQkQgQ0EgQ0IgQ0QgREEgREIgREMKICAgIHN0ZDo6c3RyaW5nIHN7IkFCQ0QifTsKICAgIHNob3cobWFrZV9wZXJtdXRhdGlvbihzLmJlZ2luKCksIHMuZW5kKCksIDIpKTsKCiAgICAvLyBFeHBlY3Q6IDAxMiAwMjEgMTAyIDEyMCAyMDEgMjEwCiAgICBzdGQ6OnZlY3RvcjxpbnQ+IHZ7MCwgMSwgMn07CiAgICBzaG93KG1ha2VfcGVybXV0YXRpb24odi5iZWdpbigpLCB2LmVuZCgpKSk7Cn0=