# Temporarily modify variable and execute within updated environment.
from time import process_time
# Class for dynamic binding of a variable.
class Parameter:
def __init__(self, v):
self.v = v
def __call__(self):
return self.v
def bind(self, v, thunk):
t = self.v
self.v = v
thunk()
self.v = t
# Memo.
def setdelayed(m, k, thunk=lambda: None):
if k not in m:
m[k] = thunk()
return m[k]
def memo(f, keyfunc=lambda x: x):
m = {}
def wrapper(*args):
return setdelayed(m, keyfunc(args), lambda: f(*args))
return wrapper
# Main.
fib = Parameter(lambda n: fib()(n-2) + fib()(n-1) if n > 1 else n)
def make_f(f):
return lambda: fib.bind(f, lambda: print(fib()(30)))
def time_f(thunk):
t = process_time()
thunk()
print('Elapsed: {:.6f}s'.format(process_time() - t))
time_f(make_f(memo(fib())))
time_f(make_f(fib()))
IyBUZW1wb3JhcmlseSBtb2RpZnkgdmFyaWFibGUgYW5kIGV4ZWN1dGUgd2l0aGluIHVwZGF0ZWQgZW52aXJvbm1lbnQuCgpmcm9tIHRpbWUgaW1wb3J0IHByb2Nlc3NfdGltZQoKIyBDbGFzcyBmb3IgZHluYW1pYyBiaW5kaW5nIG9mIGEgdmFyaWFibGUuCgpjbGFzcyBQYXJhbWV0ZXI6CiAgICBkZWYgX19pbml0X18oc2VsZiwgdik6CiAgICAgICAgc2VsZi52ID0gdgogICAgZGVmIF9fY2FsbF9fKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLnYKICAgIGRlZiBiaW5kKHNlbGYsIHYsIHRodW5rKToKICAgICAgICB0ID0gc2VsZi52CiAgICAgICAgc2VsZi52ID0gdgogICAgICAgIHRodW5rKCkKICAgICAgICBzZWxmLnYgPSB0CgojIE1lbW8uCgpkZWYgc2V0ZGVsYXllZChtLCBrLCB0aHVuaz1sYW1iZGE6IE5vbmUpOgogICAgaWYgayBub3QgaW4gbToKICAgICAgICBtW2tdID0gdGh1bmsoKQogICAgcmV0dXJuIG1ba10KCmRlZiBtZW1vKGYsIGtleWZ1bmM9bGFtYmRhIHg6IHgpOgogICAgbSA9IHt9CiAgICBkZWYgd3JhcHBlcigqYXJncyk6CiAgICAgICAgcmV0dXJuIHNldGRlbGF5ZWQobSwga2V5ZnVuYyhhcmdzKSwgbGFtYmRhOiBmKCphcmdzKSkKICAgIHJldHVybiB3cmFwcGVyCgojIE1haW4uCgpmaWIgPSBQYXJhbWV0ZXIobGFtYmRhIG46IGZpYigpKG4tMikgKyBmaWIoKShuLTEpIGlmIG4gPiAxIGVsc2UgbikKCmRlZiBtYWtlX2YoZik6CiAgICByZXR1cm4gbGFtYmRhOiBmaWIuYmluZChmLCBsYW1iZGE6IHByaW50KGZpYigpKDMwKSkpCgpkZWYgdGltZV9mKHRodW5rKToKICAgIHQgPSBwcm9jZXNzX3RpbWUoKQogICAgdGh1bmsoKQogICAgcHJpbnQoJ0VsYXBzZWQ6IHs6LjZmfXMnLmZvcm1hdChwcm9jZXNzX3RpbWUoKSAtIHQpKQoKdGltZV9mKG1ha2VfZihtZW1vKGZpYigpKSkpCnRpbWVfZihtYWtlX2YoZmliKCkpKQ==