#include <cstdio>
#include <algorithm>
int d[12];
// blank: ---- / ? ms
void blank(const int size)
{
int tot = 1, i, j, *pi;
for (i = 0; i < size; i++) d[i] = i+1, tot *= i+1;
while (tot--) {
for (i = 0; i < size-1; i++) printf("%d ", d[i]); printf("%d\n", d[i]);
// for (pi = d; *pi; pi++) printf("%d ", *pi); printf("\n");
}
}
// lexicographical_order: 64.865 ms / ? ms
void lexicographical_order(const int size)
{
int tot = 1, i, *pi, *pj, *pk, *pl;
for (i = 0; i < size; i++) d[i] = i+1, tot *= i+1;
for (pi = d, i = size-1; i; pi++, i--) printf("%d ", *pi); printf("%d\n", *pi);
while (--tot)
{
pi = d + (size - 2);
while (*pi > *(pi+1)) pi--;
pj = pi + 1;
pk = d + (size - 1);
while (pj < pk) {
std::swap(*pj, *pk);
pj++; pk--;
}
pj = d + (size - 2);
while (*pj > *pi) pj--;
std::swap(*pi, *(pj+1));
for (pi = d, i = size-1; i; pi++, i--) printf("%d ", *pi); printf("%d\n", *pi);
}
}
// incremental_way: 87.111 ms / 426.141 ms
void incremental_way(const int size)
{
int p[10], tot = 1, i, j, k, l;
for (i = 0; i < size; i++) d[i] = i+1, tot *= i+1, p[i] = tot;
tot = 0;
// for (i = 0; i < size-1; i++) j = d[i];
// for (i = 0; i < size-1; i++) printf("%d ", d[i]); printf("%d\n", d[i]);
while (++tot < p[size-1])
{
i = 0;
while (tot % p[i+1] == 0) i++;
j = 0;
k = 0;
for (j = 0; j < size; j++) {
if (d[j] <= i+1) {
d[j] = i+2 - d[j];
k = j;
} else if (d[j] == i+2) {
std::swap(d[j], d[k]);
}
}
// for (i = 0; i < size-1; i++) j = d[i];
// for (i = 0; i < size-1; i++) printf("%d ", d[i]); printf("%d\n", d[i]);
}
}
// decremental_way: 5.057 ms / 418.115 ms
void decremental_way(const int size)
{
int tot = 1, i, j, k, l;
for (i = 0; i < size; i++) d[i] = i+1, tot *= i+1;
k = size - 1;
// for (i = 0; i < size-1; i++) j = d[i];
// for (i = 0; i < size-1; i++) printf("%d ", d[i]); printf("%d\n", d[i]);
while (--tot)
{
i = 0; while (d[i] + i == size) i++;
if (i) {
j = i; while (j < size) {
if (d[j] == size-i) d[j-i] = d[j-i-1], d[j-i-1] = d[j]; else d[j-i] = d[j];
j++;
}
j = i; while (j) d[size-j] = size-j+1, j--;
k = size - 1;
} else {
std::swap(d[k], d[k-1]);
k--;
}
// for (i = 0; i < size-1; i++) j = d[i];
// for (i = 0; i < size-1; i++) printf("%d ", d[i]); printf("%d\n", d[i]);
}
}
// neighbor_swap: 33.135 ms / 419.583 ms
void neighbor_swap(const int size)
{
bool r[10];
int pre[11], nxt[11];
int tot = 1, i, j, k;
for (i = 0; i < size; i++) r[i] = false, tot *= i+1;
for (i = 1; i < size; i++) pre[i] = i-1; pre[0] = 10; nxt[10] = 0;
for (i = 0; i < size-1; i++) nxt[i] = i+1; nxt[size-1] = 10; pre[10] = size-1;
// i = 0; while (pre[i] != 10) i++; while (nxt[i] != 10) i = nxt[i];
// i = 0; while (pre[i] != 10) i++; while (nxt[i] != 10) printf("%d ", i+1), i = nxt[i]; printf("%d\n", i+1);
while (--tot)
{
i = size-1;
while ((!r[i] && pre[i] > i) || (r[i] && nxt[i] > i)) {
r[i--] ^= 1;
}
if (!r[i]) {
j = pre[i];
pre[i] = pre[j];
pre[j] = nxt[pre[i]] = i;
nxt[j] = nxt[i];
nxt[i] = pre[nxt[j]] = j;
} else {
j = nxt[i];
nxt[i] = nxt[j];
nxt[j] = pre[nxt[i]] = i;
pre[j] = pre[i];
pre[i] = nxt[pre[j]] = j;
}
// i = 0; while (pre[i] != 10) i++; while (nxt[i] != 10) i = nxt[i];
// i = 0; while (pre[i] != 10) i++; while (nxt[i] != 10) printf("%d ", i+1), i = nxt[i]; printf("%d\n", i+1);
}
}
// rotate: 41.367 ms / 429.47 ms
void rotate(const int size)
{
int tot = 1, i, j, st = 0, ed;
for (i = 0; i < size; i++) d[i] = i+1, tot *= i+1;
// i = st; j = (st ? st-1 : size-1); while (i != j) { printf("%d ", d[i++]); if (i == size) i = 0; } printf("%d\n", d[j]);
while (--tot)
{
if (d[st] == size) {
i = size - 1;
ed = st + 1; if (ed == size) ed = 0;
while (d[ed] == i) {
ed = ed + 1; if (ed == size) ed = 0;
i--;
}
d[st] = d[ed];
while (i < size) {
st = st + 1; if (st == size) st = 0;
d[st] = ++i;
}
}
st++; if (st == size) st = 0;
// i = st; j = (st ? st-1 : size-1); while (i != j) { printf("%d ", d[i++]); if (i == size) i = 0; } printf("%d\n", d[j]);
}
}
int main()
{
// blank(9);
lexicographical_order(9);
// incremental_way(10);
// decremental_way(10);
// neighbor_swap(10);
// rotate(11);
return 0;
}