#include <iostream>
#pragma mark - Tape
constexpr int Blank = -1;
template<int... xs>
class Tape {
public:
using type = Tape<xs...>;
constexpr static int length = sizeof...(xs);
};
#pragma mark - Print
template<class T>
void print(T);
template<>
void print(Tape<>) {
std::cout << std::endl;
}
template<int x, int... xs>
void print(Tape<x, xs...>) {
if (x == Blank) {
std::cout << "_ ";
} else {
std::cout << x << " ";
}
print(Tape<xs...>());
}
#pragma mark - Concatenate
template<class, class>
class Concatenate;
template<int... xs, int... ys>
class Concatenate<Tape<xs...>, Tape<ys...>> {
public:
using type = Tape<xs..., ys...>;
};
#pragma mark - Invert
template<class>
class Invert;
template<>
class Invert<Tape<>> {
public:
using type = Tape<>;
};
template<int x, int... xs>
class Invert<Tape<x, xs...>> {
public:
using type = typename Concatenate<
typename Invert<Tape<xs...>>::type,
Tape<x>
>::type;
};
int main() {
using tapeA = Tape<1, 2, 3>;
using tapeB = Tape<4, 5, 6>;
using tapeAB = typename Concatenate<tapeA, tapeB>::type;
print(tapeAB());
using tapeC = typename Invert<tapeAB>::type;
print(tapeC());
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKI3ByYWdtYSBtYXJrIC0gVGFwZQoKY29uc3RleHByIGludCBCbGFuayA9IC0xOwoKdGVtcGxhdGU8aW50Li4uIHhzPgpjbGFzcyBUYXBlIHsKcHVibGljOgogICAgdXNpbmcgdHlwZSA9IFRhcGU8eHMuLi4+OwogICAgY29uc3RleHByIHN0YXRpYyBpbnQgbGVuZ3RoID0gc2l6ZW9mLi4uKHhzKTsKfTsKCiNwcmFnbWEgbWFyayAtIFByaW50Cgp0ZW1wbGF0ZTxjbGFzcyBUPgp2b2lkIHByaW50KFQpOwoKdGVtcGxhdGU8Pgp2b2lkIHByaW50KFRhcGU8PikgewogICAgc3RkOjpjb3V0IDw8IHN0ZDo6ZW5kbDsKfQoKdGVtcGxhdGU8aW50IHgsIGludC4uLiB4cz4Kdm9pZCBwcmludChUYXBlPHgsIHhzLi4uPikgewogICAgaWYgKHggPT0gQmxhbmspIHsKICAgICAgICBzdGQ6OmNvdXQgPDwgIl8gIjsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RkOjpjb3V0IDw8IHggPDwgIiAiOwogICAgfQogICAgcHJpbnQoVGFwZTx4cy4uLj4oKSk7Cn0KCiNwcmFnbWEgbWFyayAtIENvbmNhdGVuYXRlCgp0ZW1wbGF0ZTxjbGFzcywgY2xhc3M+CmNsYXNzIENvbmNhdGVuYXRlOwoKdGVtcGxhdGU8aW50Li4uIHhzLCBpbnQuLi4geXM+CmNsYXNzIENvbmNhdGVuYXRlPFRhcGU8eHMuLi4+LCBUYXBlPHlzLi4uPj4gewpwdWJsaWM6CiAgICB1c2luZyB0eXBlID0gVGFwZTx4cy4uLiwgeXMuLi4+Owp9OwoKI3ByYWdtYSBtYXJrIC0gSW52ZXJ0Cgp0ZW1wbGF0ZTxjbGFzcz4KY2xhc3MgSW52ZXJ0OwoKdGVtcGxhdGU8PgpjbGFzcyBJbnZlcnQ8VGFwZTw+PiB7CnB1YmxpYzoKICAgIHVzaW5nIHR5cGUgPSBUYXBlPD47Cn07Cgp0ZW1wbGF0ZTxpbnQgeCwgaW50Li4uIHhzPgpjbGFzcyBJbnZlcnQ8VGFwZTx4LCB4cy4uLj4+IHsKcHVibGljOgogICAgdXNpbmcgdHlwZSA9IHR5cGVuYW1lIENvbmNhdGVuYXRlPAogICAgICAgIHR5cGVuYW1lIEludmVydDxUYXBlPHhzLi4uPj46OnR5cGUsCiAgICAgICAgVGFwZTx4PgogICAgPjo6dHlwZTsKfTsKCmludCBtYWluKCkgewoJdXNpbmcgdGFwZUEgPSBUYXBlPDEsIDIsIDM+OwoJdXNpbmcgdGFwZUIgPSBUYXBlPDQsIDUsIDY+OwoJdXNpbmcgdGFwZUFCID0gdHlwZW5hbWUgQ29uY2F0ZW5hdGU8dGFwZUEsIHRhcGVCPjo6dHlwZTsKCXByaW50KHRhcGVBQigpKTsKCQoJdXNpbmcgdGFwZUMgPSB0eXBlbmFtZSBJbnZlcnQ8dGFwZUFCPjo6dHlwZTsKCXByaW50KHRhcGVDKCkpOwoJCglyZXR1cm4gMDsKfQ==