#include <iostream>
#include <stack>
using namespace std;
int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
return fib(n - 1) + fib(n - 2);
}
struct Call {
int n;
int cur_loc;
int ret_val; // To store the return value of this call
};
int G(int n) {
Call initial_call;
initial_call.n = n;
initial_call.cur_loc = 0;
initial_call.ret_val = 0;
stack<Call> st;
st.push(initial_call);
int last_ret_val = 0;
while (!st.empty()) {
Call& call = st.top();
if (call.cur_loc == 0) {
if (call.n <= 1) {
last_ret_val = call.n;
st.pop();
}
else {
// Schedule fib(n-1) first
call.cur_loc = 1;
Call new_call;
new_call.n = call.n - 1;
new_call.cur_loc = 0;
new_call.ret_val = 0;
st.push(new_call);
}
}
else if (call.cur_loc == 1) {
// fib(n-1) has completed, store its result
call.ret_val = last_ret_val;
// Schedule fib(n-2)
call.cur_loc = 2;
Call new_call;
new_call.n = call.n - 2;
new_call.cur_loc = 0;
new_call.ret_val = 0;
st.push(new_call);
}
else if (call.cur_loc == 2) {
// fib(n-2) has completed, add it to previous result
call.ret_val += last_ret_val;
last_ret_val = call.ret_val;
st.pop();
}
}
return last_ret_val;
}
int main() {
for (int i = 0; i < 7; i++) {
cout << G(i) << " ";
}
cout << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RhY2s+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgppbnQgZmliKGludCBuKSB7CiAgICBpZiAobiA9PSAwKSByZXR1cm4gMDsKICAgIGlmIChuID09IDEpIHJldHVybiAxOwogICAgcmV0dXJuIGZpYihuIC0gMSkgKyBmaWIobiAtIDIpOwp9CgpzdHJ1Y3QgQ2FsbCB7CiAgICBpbnQgbjsKICAgIGludCBjdXJfbG9jOwogICAgaW50IHJldF92YWw7ICAvLyBUbyBzdG9yZSB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoaXMgY2FsbAp9OwoKaW50IEcoaW50IG4pIHsKICAgIENhbGwgaW5pdGlhbF9jYWxsOwogICAgaW5pdGlhbF9jYWxsLm4gPSBuOwogICAgaW5pdGlhbF9jYWxsLmN1cl9sb2MgPSAwOwogICAgaW5pdGlhbF9jYWxsLnJldF92YWwgPSAwOwoKICAgIHN0YWNrPENhbGw+IHN0OwogICAgc3QucHVzaChpbml0aWFsX2NhbGwpOwoKICAgIGludCBsYXN0X3JldF92YWwgPSAwOwoKICAgIHdoaWxlICghc3QuZW1wdHkoKSkgewogICAgICAgIENhbGwmIGNhbGwgPSBzdC50b3AoKTsKICAgICAgICAKICAgICAgICBpZiAoY2FsbC5jdXJfbG9jID09IDApIHsKICAgICAgICAgICAgaWYgKGNhbGwubiA8PSAxKSB7CiAgICAgICAgICAgICAgICBsYXN0X3JldF92YWwgPSBjYWxsLm47CiAgICAgICAgICAgICAgICBzdC5wb3AoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIC8vIFNjaGVkdWxlIGZpYihuLTEpIGZpcnN0CiAgICAgICAgICAgICAgICBjYWxsLmN1cl9sb2MgPSAxOwogICAgICAgICAgICAgICAgQ2FsbCBuZXdfY2FsbDsKICAgICAgICAgICAgICAgIG5ld19jYWxsLm4gPSBjYWxsLm4gLSAxOwogICAgICAgICAgICAgICAgbmV3X2NhbGwuY3VyX2xvYyA9IDA7CiAgICAgICAgICAgICAgICBuZXdfY2FsbC5yZXRfdmFsID0gMDsKICAgICAgICAgICAgICAgIHN0LnB1c2gobmV3X2NhbGwpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGNhbGwuY3VyX2xvYyA9PSAxKSB7CiAgICAgICAgICAgIC8vIGZpYihuLTEpIGhhcyBjb21wbGV0ZWQsIHN0b3JlIGl0cyByZXN1bHQKICAgICAgICAgICAgY2FsbC5yZXRfdmFsID0gbGFzdF9yZXRfdmFsOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gU2NoZWR1bGUgZmliKG4tMikKICAgICAgICAgICAgY2FsbC5jdXJfbG9jID0gMjsKICAgICAgICAgICAgQ2FsbCBuZXdfY2FsbDsKICAgICAgICAgICAgbmV3X2NhbGwubiA9IGNhbGwubiAtIDI7CiAgICAgICAgICAgIG5ld19jYWxsLmN1cl9sb2MgPSAwOwogICAgICAgICAgICBuZXdfY2FsbC5yZXRfdmFsID0gMDsKICAgICAgICAgICAgc3QucHVzaChuZXdfY2FsbCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGNhbGwuY3VyX2xvYyA9PSAyKSB7CiAgICAgICAgICAgIC8vIGZpYihuLTIpIGhhcyBjb21wbGV0ZWQsIGFkZCBpdCB0byBwcmV2aW91cyByZXN1bHQKICAgICAgICAgICAgY2FsbC5yZXRfdmFsICs9IGxhc3RfcmV0X3ZhbDsKICAgICAgICAgICAgbGFzdF9yZXRfdmFsID0gY2FsbC5yZXRfdmFsOwogICAgICAgICAgICBzdC5wb3AoKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gbGFzdF9yZXRfdmFsOwp9CgppbnQgbWFpbigpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNzsgaSsrKSB7CiAgICAgICAgY291dCA8PCBHKGkpIDw8ICIgIjsKICAgIH0KICAgIGNvdXQgPDwgZW5kbDsKICAgIHJldHVybiAwOwp9