//
// main.cpp
// Memoizator
//
//
#include <iostream>
#include <map>
#include <tuple>
#define MEMOIZATOR(N, R, ...) \
R _ ## N (__VA_ARGS__); \
std::map<std::tuple<__VA_ARGS__>, R> _memo_ ## N; \
template <typename ... Args> \
R N (Args ... args) { \
auto& _memo = _memo_ ## N; \
auto result = _memo.find(std::make_tuple(args...)); \
if (result != _memo.end()) { \
return result->second; \
} \
else { \
auto result = _ ## N (args...); \
_memo[std::make_tuple(args...)] = result; \
return result; \
} \
}
MEMOIZATOR(fibonacci, long int, int);
int function_count = 0;
long int _fibonacci(int n) {
function_count++;
if (n == 1 or n == 2) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
using namespace std;
int main(int argc, const char * argv[]) {
// insert code here...
cout << "Result: " << fibonacci(40) << endl;
cout << "Fibonacci executed " << function_count << " times." <<endl;
return 0;
}
Ly8KLy8gIG1haW4uY3BwCi8vICBNZW1vaXphdG9yCi8vCi8vCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPHR1cGxlPgojZGVmaW5lIE1FTU9JWkFUT1IoTiwgUiwgLi4uKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcClIgXyAjIyBOIChfX1ZBX0FSR1NfXyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKc3RkOjptYXA8c3RkOjp0dXBsZTxfX1ZBX0FSR1NfXz4sIFI+IF9tZW1vXyAjIyBOOyAgICAgICAgICAgXAp0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uIEFyZ3M+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcClIgTiAoQXJncyAuLi4gYXJncykgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGF1dG8mIF9tZW1vID0gX21lbW9fICMjIE47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgYXV0byByZXN1bHQgPSBfbWVtby5maW5kKHN0ZDo6bWFrZV90dXBsZShhcmdzLi4uKSk7ICAgICBcCiAgICBpZiAocmVzdWx0ICE9IF9tZW1vLmVuZCgpKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICByZXR1cm4gcmVzdWx0LT5zZWNvbmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBhdXRvIHJlc3VsdCA9IF8gIyMgTiAgKGFyZ3MuLi4pOyAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIF9tZW1vW3N0ZDo6bWFrZV90dXBsZShhcmdzLi4uKV0gPSByZXN1bHQ7ICAgICAgICAgICBcCiAgICAgICAgcmV0dXJuIHJlc3VsdDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAp9ICAgIApNRU1PSVpBVE9SKGZpYm9uYWNjaSwgbG9uZyBpbnQsIGludCk7CgppbnQgZnVuY3Rpb25fY291bnQgPSAwOwoKbG9uZyBpbnQgX2ZpYm9uYWNjaShpbnQgbikgewoJZnVuY3Rpb25fY291bnQrKzsKICAgIGlmIChuID09IDEgb3IgbiA9PSAyKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gZmlib25hY2NpKG4gLSAxKSArIGZpYm9uYWNjaShuIC0gMik7Cn0KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CmludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyICogYXJndltdKSB7CiAgICAvLyBpbnNlcnQgY29kZSBoZXJlLi4uCiAgICBjb3V0IDw8ICJSZXN1bHQ6ICIgPDwgZmlib25hY2NpKDQwKSA8PCBlbmRsOwogICAgY291dCA8PCAiRmlib25hY2NpIGV4ZWN1dGVkICIgPDwgZnVuY3Rpb25fY291bnQgPDwgIiB0aW1lcy4iIDw8ZW5kbDsKICAgIHJldHVybiAwOwp9Cgo=