#include <iostream>
#include <stack>
using namespace std;
int F(int n) {
// Location 0
if (n <= 0) return 0;
if (n == 1) return 1;
int x = F(n - 3);
// Location 1
int y = F(n / 2);
// Location 2
int z = x * y;
// Location 3
return n + z;
}
struct Call {
int n;
int x, y, z;
int cur_loc;
};
int G(int n) {
stack<Call> st;
Call initialCall;
initialCall.n = n;
initialCall.cur_loc = 0;
st.push(initialCall);
int last_ret_val = 0;
while(!st.empty()) {
Call& cur = st.top();
if(cur.cur_loc == 0) {
if(cur.n <= 0) {
last_ret_val = 0;
st.pop();
}
else if(cur.n == 1) {
last_ret_val = 1;
st.pop();
}
else {
// Make new child call F(n-1) and push to stack
Call new_call;
new_call.cur_loc = 0;
new_call.n = cur.n - 3;
st.push(new_call);
cur.cur_loc = 1;
}
}
else if(cur.cur_loc == 1) {
cur.x = last_ret_val;
Call new_call;
new_call.cur_loc = 0;
new_call.n = cur.n / 2;
st.push(new_call);
cur.cur_loc = 2;
}
else if(cur.cur_loc == 2) {
cur.y = last_ret_val;
cur.z = cur.x * cur.y;
cur.cur_loc = 3;
}
else if(cur.cur_loc == 3) {
last_ret_val = cur.n + cur.z;
st.pop();
}
}
return last_ret_val;
}
int main()
{
cout << "F(4) : " << F(4) << endl;
cout << "G(4): " << G(4) << endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RhY2s+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgppbnQgRihpbnQgbikgewogICAgLy8gTG9jYXRpb24gMAogICAgaWYgKG4gPD0gMCkgcmV0dXJuIDA7CiAgICBpZiAobiA9PSAxKSByZXR1cm4gMTsKICAgIAogICAgaW50IHggPSBGKG4gLSAzKTsKICAgIC8vIExvY2F0aW9uIDEKICAgIGludCB5ID0gRihuIC8gMik7CiAgICAvLyBMb2NhdGlvbiAyCiAgICBpbnQgeiA9IHggKiB5OwogICAgLy8gTG9jYXRpb24gMwogICAgcmV0dXJuIG4gKyB6Owp9CgpzdHJ1Y3QgQ2FsbCB7CiAgICBpbnQgbjsKICAgIGludCB4LCB5LCB6OwogICAgaW50IGN1cl9sb2M7Cn07CgppbnQgRyhpbnQgbikgIHsKICAgIHN0YWNrPENhbGw+IHN0OwogICAgQ2FsbCBpbml0aWFsQ2FsbDsKICAgIGluaXRpYWxDYWxsLm4gPSBuOwogICAgaW5pdGlhbENhbGwuY3VyX2xvYyAgPSAwOwogICAgc3QucHVzaChpbml0aWFsQ2FsbCk7CiAgICBpbnQgbGFzdF9yZXRfdmFsID0gMDsKICAgIHdoaWxlKCFzdC5lbXB0eSgpKSB7CiAgICAgICAgQ2FsbCYgY3VyID0gc3QudG9wKCk7CiAgICAgICAgaWYoY3VyLmN1cl9sb2MgID09IDApIHsKICAgICAgICAgICAgaWYoY3VyLm4gPD0gMCkgewogICAgICAgICAgICAgICAgbGFzdF9yZXRfdmFsID0gMDsKICAgICAgICAgICAgICAgIHN0LnBvcCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYoY3VyLm4gPT0gMSkgewogICAgICAgICAgICAgICAgbGFzdF9yZXRfdmFsID0gMTsKICAgICAgICAgICAgICAgIHN0LnBvcCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAvLyBNYWtlIG5ldyBjaGlsZCBjYWxsIEYobi0xKSBhbmQgcHVzaCB0byBzdGFjawogICAgICAgICAgICAgICAgICBDYWxsIG5ld19jYWxsOwogICAgICAgICAgICAgICAgICBuZXdfY2FsbC5jdXJfbG9jID0gMDsKICAgICAgICAgICAgICAgICAgbmV3X2NhbGwubiA9IGN1ci5uIC0gMzsKICAgICAgICAgICAgICAgICAgc3QucHVzaChuZXdfY2FsbCk7CiAgICAgICAgICAgICAgICAgIGN1ci5jdXJfbG9jID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmKGN1ci5jdXJfbG9jID09IDEpIHsKICAgICAgICAgICAgY3VyLnggPSBsYXN0X3JldF92YWw7CiAgICAgICAgICAgIENhbGwgbmV3X2NhbGw7CiAgICAgICAgICAgIG5ld19jYWxsLmN1cl9sb2MgPSAwOwogICAgICAgICAgICBuZXdfY2FsbC5uID0gY3VyLm4gLyAyOwogICAgICAgICAgICBzdC5wdXNoKG5ld19jYWxsKTsKICAgICAgICAgICAgY3VyLmN1cl9sb2MgPSAyOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihjdXIuY3VyX2xvYyA9PSAyKSB7CiAgICAgICAgICAgIGN1ci55ID0gbGFzdF9yZXRfdmFsOyAKICAgICAgICAgICAgY3VyLnogPSBjdXIueCAqIGN1ci55OwogICAgICAgICAgICAgY3VyLmN1cl9sb2MgPSAzOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKGN1ci5jdXJfbG9jID09IDMpIHsKICAgICAgICAgICAgIGxhc3RfcmV0X3ZhbCA9IGN1ci5uICsgY3VyLno7CiAgICAgICAgICAgIHN0LnBvcCgpOwogICAgICAgICAgICAKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gbGFzdF9yZXRfdmFsOwp9CgppbnQgbWFpbigpCnsKICAgIGNvdXQgPDwgIkYoNCkgOiAiIDw8IEYoNCkgPDwgZW5kbDsKICAgIGNvdXQgPDwgIkcoNCk6ICIgPDwgRyg0KSA8PCBlbmRsOwogICAKfQ==