#include <iostream>
#include <utility>
#include <vector>
template<class E, E...es>
struct elements:std::integral_constant<unsigned, sizeof...(es)> { using type=E; };
template<class E, E e0, E e1, E... es>
constexpr E next_helper( elements<E, e0, e1, es...>, E e, E first ) {
return (e0 == e)?e1:next_helper( elements<E, e1, es...>{}, e, first );
}
template<class E, E e0>
constexpr E next_helper( elements<E, e0>, E e, E first ) {
return first;
}
template<class E, E e0, E... es>
constexpr E next_helper( elements<E, e0, es...>, E e ) {
return next_helper( elements<E, e0, es...>{}, e, e0 );
}
template<class elements, class E>
constexpr E next( E e ) {
return next_helper( elements{}, e );
}
template<class elements, class E>
constexpr E next( E e, unsigned N );
template<class E, E...es>
constexpr E next_helper( elements<E,es...>, E e, unsigned N ) {
return (N>=sizeof...(es))?next<elements>( e, (N%sizeof...(es)) ):next<elements>( next<elements>( e, (N)/2 ), (N+1)/2 );
}
template<class elements, class E>
constexpr E next( E e, unsigned N ) {
return (N==0)?e:(N==1)?next<elements>(e):next_helper<elements>( next_helper<elements>( N/2, e ), (N+1)/2 );
}
template<class E, E e0, E e1, E... es>
constexpr unsigned index_helper( elements<E, e0, e1, es...>, E e ) {
return (e0==e)?0:(index_helper( elements<E, e1, es...>{}, e )+1);
}
template<class E, E e0>
constexpr unsigned index_helper( elements<E, e0>, E e ) {
return 0;
}
template<class elements, class E>
constexpr unsigned index( E e ) {
return index_helper( elements{}, e );
}
template<class E, E e0, E... es>
constexpr unsigned first_helper(elements<E, e0, es...>) {
return e0;
}
template<class elements>
constexpr auto first() -> typename elements::type {
return first_helper(elements{});
}
template<class elements>
constexpr auto nth(unsigned n) -> typename elements::type {
return next<elements>( first<elements>(), n );
}
template<typename elements>
struct iteration_tuple {
using value_type = typename elements::type;
std::vector<value_type> data;
bool advance() {
bool finished = true;
for( value_type& e : data ) {
if ( first<elements>() != ( e = next<elements>(e) ) )
finished = false;
if (!finished)
break;
}
return finished;
}
iteration_tuple( unsigned size ) {
data.resize( size, first<elements>() );
}
};
int main() {
typedef elements<int, -1, 0, 1> sequence;
iteration_tuple<sequence> sample(3);
do {
for (int x:sample.data)
std::cout << x << ",";
std::cout << "\n";
} while(!sample.advance());
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHZlY3Rvcj4KCiAgICB0ZW1wbGF0ZTxjbGFzcyBFLCBFLi4uZXM+CiAgICBzdHJ1Y3QgZWxlbWVudHM6c3RkOjppbnRlZ3JhbF9jb25zdGFudDx1bnNpZ25lZCwgc2l6ZW9mLi4uKGVzKT4geyB1c2luZyB0eXBlPUU7IH07CgogICAgdGVtcGxhdGU8Y2xhc3MgRSwgRSBlMCwgRSBlMSwgRS4uLiBlcz4KICAgIGNvbnN0ZXhwciBFIG5leHRfaGVscGVyKCBlbGVtZW50czxFLCBlMCwgZTEsIGVzLi4uPiwgRSBlLCBFIGZpcnN0ICkgewogICAgICByZXR1cm4gKGUwID09IGUpP2UxOm5leHRfaGVscGVyKCBlbGVtZW50czxFLCBlMSwgZXMuLi4+e30sIGUsIGZpcnN0ICk7CiAgICB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBFLCBFIGUwPgogICAgY29uc3RleHByIEUgbmV4dF9oZWxwZXIoIGVsZW1lbnRzPEUsIGUwPiwgRSBlLCBFIGZpcnN0ICkgewogICAgICByZXR1cm4gZmlyc3Q7CiAgICB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBFLCBFIGUwLCBFLi4uIGVzPgogICAgY29uc3RleHByIEUgbmV4dF9oZWxwZXIoIGVsZW1lbnRzPEUsIGUwLCBlcy4uLj4sIEUgZSApIHsKICAgICAgcmV0dXJuIG5leHRfaGVscGVyKCBlbGVtZW50czxFLCBlMCwgZXMuLi4+e30sIGUsIGUwICk7CiAgICB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBlbGVtZW50cywgY2xhc3MgRT4KICAgIGNvbnN0ZXhwciBFIG5leHQoIEUgZSApIHsKICAgICAgcmV0dXJuIG5leHRfaGVscGVyKCBlbGVtZW50c3t9LCBlICk7CiAgICB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBlbGVtZW50cywgY2xhc3MgRT4KICAgIGNvbnN0ZXhwciBFIG5leHQoIEUgZSwgdW5zaWduZWQgTiApOwogICAgdGVtcGxhdGU8Y2xhc3MgRSwgRS4uLmVzPgogICAgY29uc3RleHByIEUgbmV4dF9oZWxwZXIoIGVsZW1lbnRzPEUsZXMuLi4+LCBFIGUsIHVuc2lnbmVkIE4gKSB7CiAgICAgIHJldHVybiAoTj49c2l6ZW9mLi4uKGVzKSk/bmV4dDxlbGVtZW50cz4oIGUsIChOJXNpemVvZi4uLihlcykpICk6bmV4dDxlbGVtZW50cz4oIG5leHQ8ZWxlbWVudHM+KCBlLCAoTikvMiApLCAoTisxKS8yICk7CiAgICB9CiAgICB0ZW1wbGF0ZTxjbGFzcyBlbGVtZW50cywgY2xhc3MgRT4KICAgIGNvbnN0ZXhwciBFIG5leHQoIEUgZSwgdW5zaWduZWQgTiApIHsKICAgICAgcmV0dXJuIChOPT0wKT9lOihOPT0xKT9uZXh0PGVsZW1lbnRzPihlKTpuZXh0X2hlbHBlcjxlbGVtZW50cz4oIG5leHRfaGVscGVyPGVsZW1lbnRzPiggTi8yLCBlICksIChOKzEpLzIgKTsKICAgIH0KICAgIHRlbXBsYXRlPGNsYXNzIEUsIEUgZTAsIEUgZTEsIEUuLi4gZXM+CiAgICBjb25zdGV4cHIgdW5zaWduZWQgaW5kZXhfaGVscGVyKCBlbGVtZW50czxFLCBlMCwgZTEsIGVzLi4uPiwgRSBlICkgewogICAgICByZXR1cm4gKGUwPT1lKT8wOihpbmRleF9oZWxwZXIoIGVsZW1lbnRzPEUsIGUxLCBlcy4uLj57fSwgZSApKzEpOwogICAgfQogICAgdGVtcGxhdGU8Y2xhc3MgRSwgRSBlMD4KICAgIGNvbnN0ZXhwciB1bnNpZ25lZCBpbmRleF9oZWxwZXIoIGVsZW1lbnRzPEUsIGUwPiwgRSBlICkgewogICAgICByZXR1cm4gMDsKICAgIH0KICAgIHRlbXBsYXRlPGNsYXNzIGVsZW1lbnRzLCBjbGFzcyBFPgogICAgY29uc3RleHByIHVuc2lnbmVkIGluZGV4KCBFIGUgKSB7CiAgICAgIHJldHVybiBpbmRleF9oZWxwZXIoIGVsZW1lbnRze30sIGUgKTsKICAgIH0KICAgIHRlbXBsYXRlPGNsYXNzIEUsIEUgZTAsIEUuLi4gZXM+CiAgICBjb25zdGV4cHIgdW5zaWduZWQgZmlyc3RfaGVscGVyKGVsZW1lbnRzPEUsIGUwLCBlcy4uLj4pIHsKICAgICAgcmV0dXJuIGUwOwogICAgfQogICAgdGVtcGxhdGU8Y2xhc3MgZWxlbWVudHM+CiAgICBjb25zdGV4cHIgYXV0byBmaXJzdCgpIC0+IHR5cGVuYW1lIGVsZW1lbnRzOjp0eXBlIHsKICAgICAgcmV0dXJuIGZpcnN0X2hlbHBlcihlbGVtZW50c3t9KTsKICAgIH0KICAgIHRlbXBsYXRlPGNsYXNzIGVsZW1lbnRzPgogICAgY29uc3RleHByIGF1dG8gbnRoKHVuc2lnbmVkIG4pIC0+IHR5cGVuYW1lIGVsZW1lbnRzOjp0eXBlIHsKICAgICAgcmV0dXJuIG5leHQ8ZWxlbWVudHM+KCBmaXJzdDxlbGVtZW50cz4oKSwgbiApOwogICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIGVsZW1lbnRzPgogICAgc3RydWN0IGl0ZXJhdGlvbl90dXBsZSB7CiAgICAgIHVzaW5nIHZhbHVlX3R5cGUgPSB0eXBlbmFtZSBlbGVtZW50czo6dHlwZTsKICAgICAgc3RkOjp2ZWN0b3I8dmFsdWVfdHlwZT4gZGF0YTsKICAgICAgYm9vbCBhZHZhbmNlKCkgewogICAgICAgIGJvb2wgZmluaXNoZWQgPSB0cnVlOwogICAgICAgIGZvciggdmFsdWVfdHlwZSYgZSA6IGRhdGEgKSB7CiAgICAgICAgICBpZiAoIGZpcnN0PGVsZW1lbnRzPigpICE9ICggZSA9IG5leHQ8ZWxlbWVudHM+KGUpICkgKQogICAgICAgICAgICBmaW5pc2hlZCA9IGZhbHNlOwogICAgICAgICAgaWYgKCFmaW5pc2hlZCkKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHJldHVybiBmaW5pc2hlZDsKICAgICAgfQogICAgICBpdGVyYXRpb25fdHVwbGUoIHVuc2lnbmVkIHNpemUgKSB7CiAgICAgICAgZGF0YS5yZXNpemUoIHNpemUsIGZpcnN0PGVsZW1lbnRzPigpICk7CiAgICAgIH0KICAgIH07CgogICAgaW50IG1haW4oKSB7CiAgICAgIHR5cGVkZWYgZWxlbWVudHM8aW50LCAtMSwgMCwgMT4gc2VxdWVuY2U7CiAgICAgIGl0ZXJhdGlvbl90dXBsZTxzZXF1ZW5jZT4gc2FtcGxlKDMpOwogICAgICBkbyB7CiAgICAgICAgZm9yIChpbnQgeDpzYW1wbGUuZGF0YSkKICAgICAgICAgIHN0ZDo6Y291dCA8PCB4IDw8ICIsIjsKICAgICAgICBzdGQ6OmNvdXQgPDwgIlxuIjsKICAgICAgfSB3aGlsZSghc2FtcGxlLmFkdmFuY2UoKSk7CiAgICB9Cg==
-1,-1,-1,
0,-1,-1,
1,-1,-1,
-1,0,-1,
0,0,-1,
1,0,-1,
-1,1,-1,
0,1,-1,
1,1,-1,
-1,-1,0,
0,-1,0,
1,-1,0,
-1,0,0,
0,0,0,
1,0,0,
-1,1,0,
0,1,0,
1,1,0,
-1,-1,1,
0,-1,1,
1,-1,1,
-1,0,1,
0,0,1,
1,0,1,
-1,1,1,
0,1,1,
1,1,1,