#include <iostream>
#include <iomanip>
using namespace std;
class CombinationGeneratorException {};
class CombinationGenerator
{
private:
int *_list;
int *_stack;
int _size;
int _i, _j, _p, _c;
int _all;
CombinationGenerator();
public:
CombinationGenerator(int size)
: _size(size), _i(1), _j(0), _p(0), _all(0), _c(0) {
if (_size < 2) {
throw CombinationGeneratorException();
}
_list = new int[_size];
_stack = new int[_size];
}
~CombinationGenerator() {
delete [] _list;
delete [] _stack;
}
void init(int size) {
if (size < 2) {
throw CombinationGeneratorException();
}
if (size > _size) {
delete [] _list;
delete [] _stack;
_list = new int[size];
_stack = new int[size];
}
_size = size;
_all = 0;
_i = 1;
_j = _p = _c = 0;
}
void reset() {
for (_j = 0; _j < _size; _j++) {
_list[_j] = 0;
}
_i = 1;
_j = 0;
_p = 0;
_c = 0;
}
int hasNext() {
return _c != allpattern();
}
const int* get(int idx) {
if (idx < 1 || idx > allpattern()) {
throw CombinationGeneratorException();
}
while (_c != idx) {
next();
}
return _list;
}
const int* next() {
if (_i > _size) {
_list[_j] = 0;
_j++;
_i--;
}
for (;;) {
while (_j == _size) {
_i--;
if (_i < 1) {
_i = 1;
_j = 0;
_p = 0;
_c = 0;
} else {
_p--;
_j = _stack[_p];
_list[_j] = 0;
_j++;
}
}
if (_list[_j] == 0) {
_list[_j] = _i;
_i++;
if (_i > _size) {
_c++;
break;
} else {
_stack[_p] = _j;
_p++;
_j = 0;
}
} else {
_j++;
}
}
return _list;
}
int length() const {
return _size;
}
int allpattern() {
if (_all == 0) {
_all = 1;
for (int i = 2; i <= _size; i++) {
_all *= i;
}
}
return _all;
}
};
int main() {
try {
CombinationGenerator gen(15);
cout << "length: " << gen.length() << endl;
cout << "all pattern: " << gen.allpattern() << endl;
int idx = 36690094;
cout << setfill('.') << setw(10) << idx << ": ";
for (int i = 0; i < gen.length(); i++) {
cout << "_ABCDEFGHIJKLMNOPQRSTUVWXYZ"[gen.get(idx)[i]];
}
cout << endl;
} catch (CombinationGeneratorException& ex) {
cout << "error" << endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4gCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgQ29tYmluYXRpb25HZW5lcmF0b3JFeGNlcHRpb24ge307CgpjbGFzcyBDb21iaW5hdGlvbkdlbmVyYXRvcgp7CnByaXZhdGU6CglpbnQgKl9saXN0OwoJaW50ICpfc3RhY2s7CglpbnQgX3NpemU7CglpbnQgX2ksIF9qLCBfcCwgX2M7CglpbnQgX2FsbDsKCUNvbWJpbmF0aW9uR2VuZXJhdG9yKCk7CnB1YmxpYzoKCUNvbWJpbmF0aW9uR2VuZXJhdG9yKGludCBzaXplKQoJCQk6IF9zaXplKHNpemUpLCBfaSgxKSwgX2ooMCksIF9wKDApLCBfYWxsKDApLCBfYygwKSB7CgkJaWYgKF9zaXplIDwgMikgewoJCQl0aHJvdyBDb21iaW5hdGlvbkdlbmVyYXRvckV4Y2VwdGlvbigpOwoJCX0KCQlfbGlzdCA9IG5ldyBpbnRbX3NpemVdOwoJCV9zdGFjayA9IG5ldyBpbnRbX3NpemVdOwoJfQoJfkNvbWJpbmF0aW9uR2VuZXJhdG9yKCkgewoJCWRlbGV0ZSBbXSBfbGlzdDsKCQlkZWxldGUgW10gX3N0YWNrOwoJfQoJCgl2b2lkIGluaXQoaW50IHNpemUpIHsKCQlpZiAoc2l6ZSA8IDIpIHsKCQkJdGhyb3cgQ29tYmluYXRpb25HZW5lcmF0b3JFeGNlcHRpb24oKTsKCQl9CgkJaWYgKHNpemUgPiBfc2l6ZSkgewoJCQlkZWxldGUgW10gX2xpc3Q7CgkJCWRlbGV0ZSBbXSBfc3RhY2s7CgkJCV9saXN0ID0gbmV3IGludFtzaXplXTsKCQkJX3N0YWNrID0gbmV3IGludFtzaXplXTsKCQl9CgkJX3NpemUgPSBzaXplOwoJCV9hbGwgPSAwOwoJCV9pID0gMTsKCQlfaiA9IF9wID0gX2MgPSAwOwoJfQoJCgl2b2lkIHJlc2V0KCkgewoJCWZvciAoX2ogPSAwOyBfaiA8IF9zaXplOyBfaisrKSB7CgkJCV9saXN0W19qXSA9IDA7CgkJfQoJCV9pID0gMTsKCQlfaiA9IDA7CgkJX3AgPSAwOwoJCV9jID0gMDsKCX0KCQoJaW50IGhhc05leHQoKSB7CgkJcmV0dXJuIF9jICE9IGFsbHBhdHRlcm4oKTsKCX0KCQoJY29uc3QgaW50KiBnZXQoaW50IGlkeCkgewoJCWlmIChpZHggPCAxIHx8IGlkeCA+IGFsbHBhdHRlcm4oKSkgewoJCQl0aHJvdyBDb21iaW5hdGlvbkdlbmVyYXRvckV4Y2VwdGlvbigpOwoJCX0KCQl3aGlsZSAoX2MgIT0gaWR4KSB7CgkJCW5leHQoKTsKCQl9CgkJcmV0dXJuIF9saXN0OwoJfQoJCgljb25zdCBpbnQqIG5leHQoKSB7CgkJaWYgKF9pID4gX3NpemUpIHsKCQkJX2xpc3RbX2pdID0gMDsKCQkJX2orKzsKCQkJX2ktLTsKCQl9CgkJZm9yICg7OykgewoJCQl3aGlsZSAoX2ogPT0gX3NpemUpIHsKCQkJCV9pLS07CgkJCQlpZiAoX2kgPCAxKSB7CgkJCQkJX2kgPSAxOwoJCQkJCV9qID0gMDsKCQkJCQlfcCA9IDA7CgkJCQkJX2MgPSAwOwoJCQkJfSBlbHNlIHsKCQkJCQlfcC0tOwoJCQkJCV9qID0gX3N0YWNrW19wXTsKCQkJCQlfbGlzdFtfal0gPSAwOwoJCQkJCV9qKys7CgkJCQl9CgkJCX0KCQkJaWYgKF9saXN0W19qXSA9PSAwKSB7CgkJCQlfbGlzdFtfal0gPSBfaTsKCQkJCV9pKys7CgkJCQlpZiAoX2kgPiBfc2l6ZSkgewoJCQkJCV9jKys7CgkJCQkJYnJlYWs7CgkJCQl9IGVsc2UgewoJCQkJCV9zdGFja1tfcF0gPSBfajsKCQkJCQlfcCsrOwoJCQkJCV9qID0gMDsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCV9qKys7CgkJCX0KCQl9CgkJcmV0dXJuIF9saXN0OwoJfQoJCglpbnQgbGVuZ3RoKCkgY29uc3QgewoJCXJldHVybiBfc2l6ZTsKCX0KCQoJaW50IGFsbHBhdHRlcm4oKSB7CgkJaWYgKF9hbGwgPT0gMCkgewoJCQlfYWxsID0gMTsKCQkJZm9yIChpbnQgaSA9IDI7IGkgPD0gX3NpemU7IGkrKykgewoJCQkJX2FsbCAqPSBpOwoJCQl9CgkJfQoJCXJldHVybiBfYWxsOwoJfQp9OwoKCmludCBtYWluKCkgewoJCgl0cnkgewoJCUNvbWJpbmF0aW9uR2VuZXJhdG9yIGdlbigxNSk7IAoJCQoJCWNvdXQgPDwgImxlbmd0aDogIiA8PCBnZW4ubGVuZ3RoKCkgPDwgZW5kbDsgCgkJY291dCA8PCAiYWxsIHBhdHRlcm46ICIgPDwgZ2VuLmFsbHBhdHRlcm4oKSA8PCBlbmRsOwoJCQoJCWludCBpZHggPSAzNjY5MDA5NDsKCQkKCQljb3V0IDw8IHNldGZpbGwoJy4nKSA8PCBzZXR3KDEwKSA8PCBpZHggPDwgIjogIjsKCQlmb3IgKGludCBpID0gMDsgaSA8IGdlbi5sZW5ndGgoKTsgaSsrKSB7CgkJCWNvdXQgPDwgIl9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiJbZ2VuLmdldChpZHgpW2ldXTsKCQl9CgkJY291dCA8PCBlbmRsOwoKCX0gY2F0Y2ggKENvbWJpbmF0aW9uR2VuZXJhdG9yRXhjZXB0aW9uJiBleCkgewoJCWNvdXQgPDwgImVycm9yIiA8PCBlbmRsOwoJfQoJCglyZXR1cm4gMDsKfQ==