#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(In[(std::get<1>(D[i]) + In.size() - 1) % In.size()]);
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::isless(std::get<0>(A), std::get<0>(B)); });
for (std::size_t i = 0; i < V.size(); i++) {
N = std::get<1>(V[N]);
R.push_back(D[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+KEJbaV0pKSB7CgkJCQlhdXRvIEFSID0gc3RkOjpnZXQ8MD4oQVtpXSk7CgkJCQlhdXRvIEJSID0gc3RkOjpnZXQ8MD4oQltpXSk7CgkJCQlBID0gQiA9IEREOwoJCQkJcmV0dXJuIHN0ZDo6aXNsZXNzKEFSLCBCUik7CgkJCX0KCQl9CgkJQSA9IEIgPSBERDsKCQlyZXR1cm4gZmFsc2U7CgkJfSk7CgoJRFR5cGUgUjsKCXN0ZDo6c2l6ZV90IEwgPSAwOwoKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBELnNpemUoKTsgaSsrKSB7CgkJUi5wdXNoX2JhY2soSW5bKHN0ZDo6Z2V0PDE+KERbaV0pICsgSW4uc2l6ZSgpIC0gMSkgJSBJbi5zaXplKCldKTsKCQlpZiAoc3RkOjpnZXQ8MT4oRFtpXSkgPT0gMCkgeyBMID0gaTsgfQoJfQoKCXJldHVybiB7IFIsTCB9OwoKfQoKCkRUeXBlIEJsb2NrU29ydF9EZWMoY29uc3QgRFR5cGUmIEQsIHN0ZDo6c2l6ZV90IE4sIGNvbnN0IERUeXBlJiBPLCBjb25zdCBEYXRhJiBBKSB7CglzdGQ6OnZlY3RvcjxzdGQ6OnR1cGxlPFdvcmQsIHN0ZDo6c2l6ZV90Pj4gVjsKCURUeXBlIFI7CgoJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IEQuc2l6ZSgpOyBpKyspIHsKCQlWLnB1c2hfYmFjayh7IHsgRFtpXSB9LCBpIH0pOwoJfQoKCXN0ZDo6c3RhYmxlX3NvcnQoVi5iZWdpbigpLCBWLmVuZCgpLCBbXShhdXRvJiBBLCBhdXRvJiBCKSB7cmV0dXJuIHN0ZDo6aXNsZXNzKHN0ZDo6Z2V0PDA+KEEpLCBzdGQ6OmdldDwwPihCKSk7IH0pOwoKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBWLnNpemUoKTsgaSsrKSB7CgkJTiA9IHN0ZDo6Z2V0PDE+KFZbTl0pOwoJCVIucHVzaF9iYWNrKERbTl0pOwoJfQoJLy9zdGQ6OnJvdGF0ZShSLmJlZ2luKCksIFIuYmVnaW4oKSsxLCBSLmVuZCgpKTsKCS8vc3RkOjpyb3RhdGUoUi5iZWdpbigpLCBSLmVuZCgpLU4sIFIuZW5kKCkpOwoJLy9zdGQ6OnJldmVyc2UoUi5iZWdpbigpLCBSLmVuZCgpKTsKCglyZXR1cm4gUjsKfQoKRFR5cGUgTWFrZUNhY2FvKCkgewoJRFR5cGUgUiA9IHsgJ2MnLCdhJywnYycsJ2EnLCdvJyB9OwoKCXJldHVybiBSOwp9CgpEVHlwZSBNYWtlX2NkZWJhYWFhKCkgewoJRFR5cGUgUiA9IHsgJ2MnLCdkJywnZScsJ2InLCdhJywnYScsJ2EnLCdhJyB9OwoKCXJldHVybiBSOwp9CkRUeXBlIE1ha2VQYXBheWEoKSB7CglEVHlwZSBSID0geyAncCcsJ2EnLCdwJywnYScsJ3knLCdhJywgfTsKCglyZXR1cm4gUjsKfQpEVHlwZSBNYWtlQmFuYW5hKCkgewoJRFR5cGUgUiA9IHsgJ2InLCdhJywnbicsJ2EnLCduJywnYScsIH07CgoJcmV0dXJuIFI7Cn0KRFR5cGUgTWFrZVZlY29yKHN0ZDo6c2l6ZV90IEwsIHVuc2lnbmVkIGludCBTID0gMCkgewoJRFR5cGUgUjsKCXN0ZDo6bXQxOTkzNyBtdChTKTsKCXN0ZDo6dW5pZm9ybV9pbnRfZGlzdHJpYnV0aW9uPGludD4gdWkoMCwgMjU1KTsKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBMOyBpKyspIHsKCQlSLnB1c2hfYmFjayh1aShtdCkpOwoJfQoKCXJldHVybiBSOwp9CkRUeXBlIE1ha2VWZWNvcjIoc3RkOjpzaXplX3QgTCwgdW5zaWduZWQgaW50IFMgPSAwKSB7CglEVHlwZSBSOwoJc3RkOjptdDE5OTM3IG10KFMpOwoJc3RkOjp1bmlmb3JtX2ludF9kaXN0cmlidXRpb248aW50PiB1aSgnQScsICd6Jyk7Cglmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgTDsgaSsrKSB7CgkJUi5wdXNoX2JhY2sodWkobXQpKTsKCX0KCglyZXR1cm4gUjsKfQoKYm9vbCBTaG93KGNvbnN0IERUeXBlJiBJbikgewoJZm9yIChhdXRvJiBvIDogSW4pIHsKCQlzdGQ6OmNvdXQgPDwgbyA8PCAnLCc7Cgl9CgoJc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKCglyZXR1cm4gdHJ1ZTsKfQppbnQgbWFpbigpIHsKCS8vYXV0byBEID0gTWFrZUNhY2FvKCk7CgkvL2F1dG8gRCA9IE1ha2VfY2RlYmFhYWEoKTsKCS8vYXV0byBEID0gTWFrZVBhcGF5YSgpOwoJLy9hdXRvIEQgPSBNYWtlQmFuYW5hKCk7IAoJYXV0byBEID0gTWFrZVZlY29yMig4LCAyKTsKCS8vYXV0byBEID0gTWFrZVZlY29yMigxMjgpOwoKCVNob3coRCk7CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoKCWF1dG8gQSA9IEJsb2NrU29ydF9FbmMoRCk7CgoJU2hvdyhzdGQ6OmdldDwwPihBKSk7CglzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoKCWF1dG8gQiA9IEJsb2NrU29ydF9EZWMoc3RkOjpnZXQ8MD4oQSksIHN0ZDo6Z2V0PDE+KEEpLCBELCBBKTsKCglTaG93KEIpOwoJc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKCWlmIChEID09IEIpIHsKCQlzdGQ6OmNvdXQgPDwgc3RkOjplbmRsIDw8ICJnb29kIiA8PCBzdGQ6OmVuZGw7Cgl9CgllbHNlIHsKCQlzdGQ6OmNvdXQgPDwgc3RkOjplbmRsIDw8ICJCYWQiIDw8IHN0ZDo6ZW5kbDsKCX0KCglyZXR1cm4gMDsKCgoKfQ==