#include <iostream>
#include <tuple>
#include <map>
#include <cstdint>
using Tiii = std::tuple<int, int, int>;
using Mti = std::map<Tiii, int>;
Mti mti;
std::uint64_t count = 0;
int Tarai(int x, int y, int z)
{
count++;
if (x <= y)
return y;
else {
auto tp = std::make_tuple(x, y, z);
auto tiiip = mti.find(tp);
if (tiiip != mti.end())
return tiiip->second;
else {
int xx = mti[std::make_tuple(x - 1, y, z)] = Tarai(x - 1, y, z);
int yy = mti[std::make_tuple(y - 1, z, x)] = Tarai(y - 1, z, x);
int zz = mti[std::make_tuple(z - 1, x, y)] = Tarai(z - 1, x, y);
return mti[std::make_tuple(xx, yy, zz)] = Tarai(xx, yy, zz);
}
}
}
int main()
{
int x = 100, y = 50, z = 0;
std::cout << "Tarai(" << x << "," << y << "," << z <<") = " << Tarai(x, y, z) << std::endl;
std::cout << "Tarai() called " << count << " time(s)." << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDxjc3RkaW50PgoKdXNpbmcgVGlpaSA9IHN0ZDo6dHVwbGU8aW50LCBpbnQsIGludD47CnVzaW5nIE10aSA9IHN0ZDo6bWFwPFRpaWksIGludD47CgpNdGkgbXRpOwpzdGQ6OnVpbnQ2NF90IGNvdW50ID0gMDsKCmludCBUYXJhaShpbnQgeCwgaW50IHksIGludCB6KQp7CiAgY291bnQrKzsKCiAgaWYgKHggPD0geSkKICAgIHJldHVybiB5OwogIGVsc2UgewogICAgYXV0byB0cCA9IHN0ZDo6bWFrZV90dXBsZSh4LCB5LCB6KTsKICAgIGF1dG8gdGlpaXAgPSBtdGkuZmluZCh0cCk7CiAgICBpZiAodGlpaXAgIT0gbXRpLmVuZCgpKQogICAgICByZXR1cm4gdGlpaXAtPnNlY29uZDsKICAgIGVsc2UgewogICAgICBpbnQgeHggPSBtdGlbc3RkOjptYWtlX3R1cGxlKHggLSAxLCB5LCB6KV0gPSBUYXJhaSh4IC0gMSwgeSwgeik7CiAgICAgIGludCB5eSA9IG10aVtzdGQ6Om1ha2VfdHVwbGUoeSAtIDEsIHosIHgpXSA9IFRhcmFpKHkgLSAxLCB6LCB4KTsKICAgICAgaW50IHp6ID0gbXRpW3N0ZDo6bWFrZV90dXBsZSh6IC0gMSwgeCwgeSldID0gVGFyYWkoeiAtIDEsIHgsIHkpOwogICAgICByZXR1cm4gbXRpW3N0ZDo6bWFrZV90dXBsZSh4eCwgeXksIHp6KV0gPSBUYXJhaSh4eCwgeXksIHp6KTsKICAgIH0KICB9Cn0KCmludCBtYWluKCkKewogIGludCB4ID0gMTAwLCB5ID0gNTAsIHogPSAwOwogCiAgc3RkOjpjb3V0IDw8ICJUYXJhaSgiIDw8IHggPDwgIiwiIDw8IHkgPDwgIiwiIDw8IHogPDwiKSA9ICIgPDwgVGFyYWkoeCwgeSwgeikgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCAiVGFyYWkoKSBjYWxsZWQgIiA8PCBjb3VudCA8PCAiIHRpbWUocykuIiA8PCBzdGQ6OmVuZGw7Cn0KCiA=