#include <iostream>
struct nil {};
template <int head, typename tail> struct cons;
template <int... list> struct variadic2list;
template <int head, int... rest>
struct variadic2list<head, rest...> {
typedef cons<head, typename variadic2list<rest...>::type> type;
};
template <> struct variadic2list<> { typedef nil type; };
template <typename typelist>
struct printlist {
template <typename T>
static void print(T& os) {}
};
template <int head, typename tail>
struct printlist<cons<head, tail>> {
template <typename T>
static void print(T& os) {
os << head;
printlist<tail>::print(os);
}
};
template <int val, int count, typename rest> struct single_look_and_say;
template <int val, int count, int next, typename rest>
struct single_look_and_say<val, count, cons<next, rest>> {
typedef cons<count, cons<val, typename single_look_and_say<next, 1, rest>::type>> type;
};
template <int val, int count, typename rest>
struct single_look_and_say<val, count, cons<val, rest>> {
typedef typename single_look_and_say<val, count + 1, rest>::type type;
};
template <int val, int count>
struct single_look_and_say<val, count, nil> {
typedef typename variadic2list<count, val>::type type;
};
template <size_t iters, typename seq> struct look_and_say_impl;
template <size_t iters, int head, typename tail>
struct look_and_say_impl<iters, cons<head, tail>> {
typedef typename look_and_say_impl<iters - 1,
typename single_look_and_say<head, 1, tail>::type>::type type;
};
// I need to pull apart head and tail to tell the compiler that this is more specialized.
template <int head, typename tail>
struct look_and_say_impl<1, cons<head, tail>> {
typedef cons<head, tail> type;
};
template <size_t iters, int... seed>
struct look_and_say {
typedef typename look_and_say_impl<iters, typename variadic2list<seed...>::type>::type type;
};
// Seed defaults to 1
template <size_t iters>
struct look_and_say<iters> {
typedef typename look_and_say<iters, 1>::type type;
};
int main() {
printlist<look_and_say<6>::type>::print(std::cout); // 6th value
std::cout << '\n';
printlist<look_and_say<4, 2, 2>::type>::print(std::cout); // 4th value from 22
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IG5pbCB7fTsKdGVtcGxhdGUgPGludCBoZWFkLCB0eXBlbmFtZSB0YWlsPiBzdHJ1Y3QgY29uczsKCnRlbXBsYXRlIDxpbnQuLi4gbGlzdD4gc3RydWN0IHZhcmlhZGljMmxpc3Q7CnRlbXBsYXRlIDxpbnQgaGVhZCwgaW50Li4uIHJlc3Q+CnN0cnVjdCB2YXJpYWRpYzJsaXN0PGhlYWQsIHJlc3QuLi4+IHsKCXR5cGVkZWYgY29uczxoZWFkLCB0eXBlbmFtZSB2YXJpYWRpYzJsaXN0PHJlc3QuLi4+Ojp0eXBlPiB0eXBlOwp9Owp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgdmFyaWFkaWMybGlzdDw+IHsgdHlwZWRlZiBuaWwgdHlwZTsgfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSB0eXBlbGlzdD4Kc3RydWN0IHByaW50bGlzdCB7Cgl0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KCXN0YXRpYyB2b2lkIHByaW50KFQmIG9zKSB7fQp9Owp0ZW1wbGF0ZSA8aW50IGhlYWQsIHR5cGVuYW1lIHRhaWw+CnN0cnVjdCBwcmludGxpc3Q8Y29uczxoZWFkLCB0YWlsPj4gewoJdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CglzdGF0aWMgdm9pZCBwcmludChUJiBvcykgewoJCW9zIDw8IGhlYWQ7CgkJcHJpbnRsaXN0PHRhaWw+OjpwcmludChvcyk7Cgl9Cn07Cgp0ZW1wbGF0ZSA8aW50IHZhbCwgaW50IGNvdW50LCB0eXBlbmFtZSByZXN0PiBzdHJ1Y3Qgc2luZ2xlX2xvb2tfYW5kX3NheTsKdGVtcGxhdGUgPGludCB2YWwsIGludCBjb3VudCwgaW50IG5leHQsIHR5cGVuYW1lIHJlc3Q+CnN0cnVjdCBzaW5nbGVfbG9va19hbmRfc2F5PHZhbCwgY291bnQsIGNvbnM8bmV4dCwgcmVzdD4+IHsKCXR5cGVkZWYgY29uczxjb3VudCwgY29uczx2YWwsIHR5cGVuYW1lIHNpbmdsZV9sb29rX2FuZF9zYXk8bmV4dCwgMSwgcmVzdD46OnR5cGU+PiB0eXBlOwp9Owp0ZW1wbGF0ZSA8aW50IHZhbCwgaW50IGNvdW50LCB0eXBlbmFtZSByZXN0PgpzdHJ1Y3Qgc2luZ2xlX2xvb2tfYW5kX3NheTx2YWwsIGNvdW50LCBjb25zPHZhbCwgcmVzdD4+IHsKCXR5cGVkZWYgdHlwZW5hbWUgc2luZ2xlX2xvb2tfYW5kX3NheTx2YWwsIGNvdW50ICsgMSwgcmVzdD46OnR5cGUgdHlwZTsKfTsKdGVtcGxhdGUgPGludCB2YWwsIGludCBjb3VudD4Kc3RydWN0IHNpbmdsZV9sb29rX2FuZF9zYXk8dmFsLCBjb3VudCwgbmlsPiB7Cgl0eXBlZGVmIHR5cGVuYW1lIHZhcmlhZGljMmxpc3Q8Y291bnQsIHZhbD46OnR5cGUgdHlwZTsKfTsKCnRlbXBsYXRlIDxzaXplX3QgaXRlcnMsIHR5cGVuYW1lIHNlcT4gc3RydWN0IGxvb2tfYW5kX3NheV9pbXBsOwp0ZW1wbGF0ZSA8c2l6ZV90IGl0ZXJzLCBpbnQgaGVhZCwgdHlwZW5hbWUgdGFpbD4Kc3RydWN0IGxvb2tfYW5kX3NheV9pbXBsPGl0ZXJzLCBjb25zPGhlYWQsIHRhaWw+PiB7Cgl0eXBlZGVmIHR5cGVuYW1lIGxvb2tfYW5kX3NheV9pbXBsPGl0ZXJzIC0gMSwKCQl0eXBlbmFtZSBzaW5nbGVfbG9va19hbmRfc2F5PGhlYWQsIDEsIHRhaWw+Ojp0eXBlPjo6dHlwZSB0eXBlOwp9OwovLyBJIG5lZWQgdG8gcHVsbCBhcGFydCBoZWFkIGFuZCB0YWlsIHRvIHRlbGwgdGhlIGNvbXBpbGVyIHRoYXQgdGhpcyBpcyBtb3JlIHNwZWNpYWxpemVkLgp0ZW1wbGF0ZSA8aW50IGhlYWQsIHR5cGVuYW1lIHRhaWw+CnN0cnVjdCBsb29rX2FuZF9zYXlfaW1wbDwxLCBjb25zPGhlYWQsIHRhaWw+PiB7Cgl0eXBlZGVmIGNvbnM8aGVhZCwgdGFpbD4gdHlwZTsKfTsKCnRlbXBsYXRlIDxzaXplX3QgaXRlcnMsIGludC4uLiBzZWVkPgpzdHJ1Y3QgbG9va19hbmRfc2F5IHsKCXR5cGVkZWYgdHlwZW5hbWUgbG9va19hbmRfc2F5X2ltcGw8aXRlcnMsIHR5cGVuYW1lIHZhcmlhZGljMmxpc3Q8c2VlZC4uLj46OnR5cGU+Ojp0eXBlIHR5cGU7Cn07Ci8vIFNlZWQgZGVmYXVsdHMgdG8gMQp0ZW1wbGF0ZSA8c2l6ZV90IGl0ZXJzPgpzdHJ1Y3QgbG9va19hbmRfc2F5PGl0ZXJzPiB7Cgl0eXBlZGVmIHR5cGVuYW1lIGxvb2tfYW5kX3NheTxpdGVycywgMT46OnR5cGUgdHlwZTsKfTsKCmludCBtYWluKCkgewoJcHJpbnRsaXN0PGxvb2tfYW5kX3NheTw2Pjo6dHlwZT46OnByaW50KHN0ZDo6Y291dCk7ICAgICAgIC8vIDZ0aCB2YWx1ZQoJc3RkOjpjb3V0IDw8ICdcbic7CglwcmludGxpc3Q8bG9va19hbmRfc2F5PDQsIDIsIDI+Ojp0eXBlPjo6cHJpbnQoc3RkOjpjb3V0KTsgLy8gNHRoIHZhbHVlIGZyb20gMjIKCXJldHVybiAwOwp9