Memoize a recursive Fibonacci
Plain recursive Fibonacci recomputes the same subtrees exponentially often — fib(50) is roughly forty billion calls. Adding a cache in the enclosing scope turns it linear, and it is the clearest demonstration there is of why a closure over mutable state is useful.
Implement createFib(). It returns a function fib(n) where fib(0) is 0, fib(1) is 1, and fib(n) is fib(n - 1) + fib(n - 2). Results are cached in the closure, so the cache survives between separate top-level calls to fib. The returned function also exposes a misses property counting the cache misses: every time fib is called with an n that is not already in the cache, misses rises by one and the computed value is cached — including the base cases 0 and 1. So a freshly created fib called once with 10 ends up with misses of 11, and calling fib(10) again adds nothing. Each call to createFib() produces an independent function with its own empty cache and its own misses of 0.
Returns
((n: number) => number) & { misses: number } — A memoised fib(n) whose closure caches every computed value, plus a live misses counter.
Examples
const fib = createFib();
fib(0); // 0
fib(1); // 1
fib(7); // 13
fib(50); // 12586269025 — instantconst fib = createFib();
fib(10);
fib.misses; // 11 — one per cached value, base cases included
fib(10);
fib.misses; // 11 — cache hit, no new work
fib(12);
fib.misses; // 13 — only 11 and 12 were newThe win: naive recursive fib(50) is roughly 40 billion calls. Memoised, it is 51.
What it has to do
- Return correct Fibonacci numbers, with
fib(0)of0andfib(1)of1. - Cache results in the closure so
fib(50)returns immediately. - Keep the cache between separate calls to
fib. - Track
misses: one pernthat had to be computed, base cases included. - Give each
createFib()its own cache and its ownmissescounter.
Notes
- The cache has to live in
createFib's scope, not insidefib, so recursive calls share it. If you built the cache insidefib, every call would start empty. fib(50)is12586269025— bigger than2^32but still withinNumber.MAX_SAFE_INTEGER. You hit the safe-integer ceiling aroundfib(78); useBigIntbeyond that.
Stuck? The javascript course covers everything this challenge needs.
- 1.computes the base cases and small values
- 2.returns fib(50) without recomputing subtrees
- 3.counts one miss per computed value and reuses the cache
- 4.only computes the new values when n grows
- 5.each instance has its own cache
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.