#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <tuple>
#include <random>
typedef std::uint8_t Word;
typedef std::vector<Word> DType;
typedef std::vector<DType> DTypes;
typedef std::tuple<DType, std::size_t> Data;
Data BlockSort_Enc(const DType& In) {
std::vector<std::tuple<Word, std::size_t>> D;
for (std::size_t i = 0; i < In.size(); i++) {
D.push_back({ In[i],i });
}
auto DD = D;
auto A = D;
auto B = D;
auto& X = D;
std::stable_sort(D.begin(), D.end(), [&](auto& AA, auto& BB) {
std::rotate(A.begin(), A.begin() + (std::get<1>(AA) % A.size()), A.end());
std::rotate(B.begin(), B.begin() + (std::get<1>(BB) % B.size()), B.end());
for (std::size_t i = 0; i < X.size(); i++) {
if (std::get<0>(A[i]) != std::get<0>(B[i])) {
auto AR = std::get<0>(A[i]);
auto BR = std::get<0>(B[i]);
A = B = DD;
return std::isless(AR, BR);
}
}
A = B = DD;
return false;
});
DType R;
std::size_t L=0;
for (std::size_t i = 0; i < D.size(); i++) {
R.push_back(std::get<0>(D[i]));
if (std::get<1>(D[i]) == 0) { L = i; }
}
return { R,L};
}
DType BlockSort_Dec(const DType& D, std::size_t N,const DType& O,const Data& A) {
std::vector<std::tuple<Word, std::size_t>> V;
DType R;
for (std::size_t i = 0; i < D.size(); i++) {
V.push_back({ { D[i] }, i });
}
std::stable_sort(V.begin(), V.end(), [](auto& A, auto& B) {return std::isgreater(std::get<0>(A), std::get<0>(B)); });
for (std::size_t i = 0; i <V.size(); i++) {
R.push_back(std::get<0>(V[N]));
N = std::get<1>(V[N]);
}
//std::rotate(R.begin(), R.begin()+1, R.end());
//std::rotate(R.begin(), R.end()-N, R.end());
std::reverse(R.begin(), R.end());
return R;
}
DType MakeCacao() {
DType R = { 'c','a','c','a','o'};
return R;
}
DType Make_cdebaaaa() {
DType R = { 'c','d','e','b','a','a','a','a'};
return R;
}
DType MakePapaya() {
DType R = { 'p','a','p','a','y','a',};
return R;
}
DType MakeBanana() {
DType R = { 'b','a','n','a','n','a',};
return R;
}
DType MakeVecor(std::size_t L, unsigned int S = 0) {
DType R;
std::mt19937 mt(S);
std::uniform_int_distribution<int> ui(0, 255);
for (std::size_t i = 0; i < L; i++) {
R.push_back(ui(mt));
}
return R;
}
DType MakeVecor2(std::size_t L, unsigned int S = 0) {
DType R;
std::mt19937 mt(S);
std::uniform_int_distribution<int> ui('A', 'z');
for (std::size_t i = 0; i < L; i++) {
R.push_back(ui(mt));
}
return R;
}
bool Show(const DType& In) {
for (auto& o : In) {
std::cout << o << ',';
}
std::cout << std::endl;
return true;
}
int main() {
//auto D = MakeCacao();
//auto D = Make_cdebaaaa();
//auto D = MakePapaya();
//auto D = MakeBanana();
auto D = MakeVecor2(8,2);
//auto D = MakeVecor2(128);
Show(D);
std::cout << std::endl;
auto A = BlockSort_Enc(D);
Show(std::get<0>(A));
std::cout << std::endl;
auto B = BlockSort_Dec(std::get<0>(A), std::get<1>(A),D,A);
Show(B);
std::cout << std::endl;
if (D == B) {
std::cout<< std::endl << "good" << std::endl;
}else{
std::cout<< std::endl << "Bad" << std::endl;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8cmFuZG9tPgoKdHlwZWRlZiBzdGQ6OnVpbnQ4X3QgV29yZDsKdHlwZWRlZiBzdGQ6OnZlY3RvcjxXb3JkPiBEVHlwZTsKdHlwZWRlZiBzdGQ6OnZlY3RvcjxEVHlwZT4gRFR5cGVzOwp0eXBlZGVmIHN0ZDo6dHVwbGU8RFR5cGUsIHN0ZDo6c2l6ZV90PiBEYXRhOwoKRGF0YSBCbG9ja1NvcnRfRW5jKGNvbnN0IERUeXBlJiBJbikgewoJc3RkOjp2ZWN0b3I8c3RkOjp0dXBsZTxXb3JkLCBzdGQ6OnNpemVfdD4+IEQ7CgoJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IEluLnNpemUoKTsgaSsrKSB7CgkJRC5wdXNoX2JhY2soeyBJbltpXSxpIH0pOwoJfQoKCWF1dG8gREQgPSBEOwoJYXV0byBBID0gRDsKCWF1dG8gQiA9IEQ7CglhdXRvJiBYID0gRDsKCglzdGQ6OnN0YWJsZV9zb3J0KEQuYmVnaW4oKSwgRC5lbmQoKSwgWyZdKGF1dG8mIEFBLCBhdXRvJiBCQikgewoJCXN0ZDo6cm90YXRlKEEuYmVnaW4oKSwgQS5iZWdpbigpICsgKHN0ZDo6Z2V0PDE+KEFBKSAlIEEuc2l6ZSgpKSwgQS5lbmQoKSk7CgkJc3RkOjpyb3RhdGUoQi5iZWdpbigpLCBCLmJlZ2luKCkgKyAoc3RkOjpnZXQ8MT4oQkIpICUgQi5zaXplKCkpLCBCLmVuZCgpKTsKCgkJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IFguc2l6ZSgpOyBpKyspIHsKCQkJaWYgKHN0ZDo6Z2V0PDA+KEFbaV0pICE9IHN0ZDo6Z2V0PDA+KEJbaV0pKSB7CgkJCQlhdXRvIEFSID0gc3RkOjpnZXQ8MD4oQVtpXSk7CgkJCQlhdXRvIEJSID0gc3RkOjpnZXQ8MD4oQltpXSk7CgkJCQlBID0gQiA9IEREOwoJCQkJcmV0dXJuIHN0ZDo6aXNsZXNzKEFSLCBCUik7CgkJCX0KCQl9CgkJQSA9IEIgPSBERDsKCQlyZXR1cm4gZmFsc2U7CgkJfSk7CgoJRFR5cGUgUjsKCXN0ZDo6c2l6ZV90IEw9MDsKCglmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgRC5zaXplKCk7IGkrKykgewoJCVIucHVzaF9iYWNrKHN0ZDo6Z2V0PDA+KERbaV0pKTsKCQlpZiAoc3RkOjpnZXQ8MT4oRFtpXSkgPT0gMCkgeyBMID0gaTsgfQoJfQoKCXJldHVybiB7IFIsTH07Cgp9CgoKRFR5cGUgQmxvY2tTb3J0X0RlYyhjb25zdCBEVHlwZSYgRCwgc3RkOjpzaXplX3QgTixjb25zdCBEVHlwZSYgTyxjb25zdCBEYXRhJiBBKSB7CglzdGQ6OnZlY3RvcjxzdGQ6OnR1cGxlPFdvcmQsIHN0ZDo6c2l6ZV90Pj4gVjsKCURUeXBlIFI7CgoJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IEQuc2l6ZSgpOyBpKyspIHsKCQlWLnB1c2hfYmFjayh7IHsgRFtpXSB9LCBpIH0pOwoJfQoKCXN0ZDo6c3RhYmxlX3NvcnQoVi5iZWdpbigpLCBWLmVuZCgpLCBbXShhdXRvJiBBLCBhdXRvJiBCKSB7cmV0dXJuIHN0ZDo6aXNncmVhdGVyKHN0ZDo6Z2V0PDA+KEEpLCBzdGQ6OmdldDwwPihCKSk7IH0pOwoKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPFYuc2l6ZSgpOyBpKyspIHsKCQlSLnB1c2hfYmFjayhzdGQ6OmdldDwwPihWW05dKSk7CQoJCU4gPSBzdGQ6OmdldDwxPihWW05dKTsKCX0KCS8vc3RkOjpyb3RhdGUoUi5iZWdpbigpLCBSLmJlZ2luKCkrMSwgUi5lbmQoKSk7CgkvL3N0ZDo6cm90YXRlKFIuYmVnaW4oKSwgUi5lbmQoKS1OLCBSLmVuZCgpKTsKCXN0ZDo6cmV2ZXJzZShSLmJlZ2luKCksIFIuZW5kKCkpOwoKCXJldHVybiBSOwp9CgpEVHlwZSBNYWtlQ2FjYW8oKSB7CglEVHlwZSBSID0geyAnYycsJ2EnLCdjJywnYScsJ28nfTsKCglyZXR1cm4gUjsKfQoKRFR5cGUgTWFrZV9jZGViYWFhYSgpIHsKCURUeXBlIFIgPSB7ICdjJywnZCcsJ2UnLCdiJywnYScsJ2EnLCdhJywnYSd9OwoKCXJldHVybiBSOwp9CkRUeXBlIE1ha2VQYXBheWEoKSB7CglEVHlwZSBSID0geyAncCcsJ2EnLCdwJywnYScsJ3knLCdhJyx9OwoKCXJldHVybiBSOwp9CkRUeXBlIE1ha2VCYW5hbmEoKSB7CglEVHlwZSBSID0geyAnYicsJ2EnLCduJywnYScsJ24nLCdhJyx9OwoKCXJldHVybiBSOwp9CkRUeXBlIE1ha2VWZWNvcihzdGQ6OnNpemVfdCBMLCB1bnNpZ25lZCBpbnQgUyA9IDApIHsKCURUeXBlIFI7CglzdGQ6Om10MTk5MzcgbXQoUyk7CglzdGQ6OnVuaWZvcm1faW50X2Rpc3RyaWJ1dGlvbjxpbnQ+IHVpKDAsIDI1NSk7Cglmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgTDsgaSsrKSB7CgkJUi5wdXNoX2JhY2sodWkobXQpKTsKCX0KCglyZXR1cm4gUjsKfQpEVHlwZSBNYWtlVmVjb3IyKHN0ZDo6c2l6ZV90IEwsIHVuc2lnbmVkIGludCBTID0gMCkgewoJRFR5cGUgUjsKCXN0ZDo6bXQxOTkzNyBtdChTKTsKCXN0ZDo6dW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGludD4gdWkoJ0EnLCAneicpOwoJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IEw7IGkrKykgewoJCVIucHVzaF9iYWNrKHVpKG10KSk7Cgl9CgoJcmV0dXJuIFI7Cn0KCmJvb2wgU2hvdyhjb25zdCBEVHlwZSYgSW4pIHsKCWZvciAoYXV0byYgbyA6IEluKSB7CgkJc3RkOjpjb3V0IDw8IG8gPDwgJywnOwoJfQoKCXN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7CgoJcmV0dXJuIHRydWU7Cn0KaW50IG1haW4oKSB7CgkvL2F1dG8gRCA9IE1ha2VDYWNhbygpOwoJLy9hdXRvIEQgPSBNYWtlX2NkZWJhYWFhKCk7CgkvL2F1dG8gRCA9IE1ha2VQYXBheWEoKTsKCS8vYXV0byBEID0gTWFrZUJhbmFuYSgpOyAKCWF1dG8gRCA9IE1ha2VWZWNvcjIoOCwyKTsKCS8vYXV0byBEID0gTWFrZVZlY29yMigxMjgpOwoJCglTaG93KEQpOwoJc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKCglhdXRvIEEgPSBCbG9ja1NvcnRfRW5jKEQpOwoKCVNob3coc3RkOjpnZXQ8MD4oQSkpOwoJc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKCglhdXRvIEIgPSBCbG9ja1NvcnRfRGVjKHN0ZDo6Z2V0PDA+KEEpLCBzdGQ6OmdldDwxPihBKSxELEEpOwoKCVNob3coQik7CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJaWYgKEQgPT0gQikgewoJCXN0ZDo6Y291dDw8IHN0ZDo6ZW5kbCA8PCAiZ29vZCIgPDwgc3RkOjplbmRsOwoJfWVsc2V7CgkJc3RkOjpjb3V0PDwgc3RkOjplbmRsIDw8ICJCYWQiIDw8IHN0ZDo6ZW5kbDsKCX0KCglyZXR1cm4gMDsKCQoKCn0=