Skip to content

Instantly share code, notes, and snippets.

@dkorolev
Last active July 2, 2024 12:39
Show Gist options
  • Save dkorolev/c6038ac26474e546c91776c349975c8b to your computer and use it in GitHub Desktop.
Save dkorolev/c6038ac26474e546c91776c349975c8b to your computer and use it in GitHub Desktop.
function memoizer(fn) {
if (typeof fn !== 'function') {
console.error('Need a function.');
return () => {};
} else {
return (() => {
const cache = {};
eval(`
function memoized(...args) {
const impl = ${fn.toString().replace('{', `{ const ${fn.name} = memoized; `)}
const key = JSON.stringify(args);
if (key in cache) {
console.log('Using the value from the cache for args=' + key);
return cache[key];
} else {
const r = impl(...args);
cache[key] = r;
return r;
}
};
`);
return memoized;
})();
}
}
// Demo `factorial(n)`.
function factorial(n) {
console.log(`Computing factorial for N=${n}`);
return n <= 0 ? 1 : n * factorial(n - 1);
}
const memoizedFactorial = memoizer(factorial);
console.log('First call to `factorial` to warm the cache.');
console.log(memoizedFactorial(5));
console.log('Next call to `factorial` to use the cache.');
console.log(memoizedFactorial(4));
// Demo `nchoosek(n,k)`, two arguments and define a function via `=>` instead.
// Note that it is using the cache even during the evaluation of the first, "warmup" call.
const nchoosek = (n, k) => {
console.log(`Computing nchoosek for N=${n}, K=${k}`);
if (k <= 0 || k >= n) {
return 1;
} else {
return nchoosek(n-1, k) + nchoosek(n-1, k-1);
}
};
const memoizedNchoosek = memoizer(nchoosek);
console.log('First call to `nchoosek` to warm the cache.');
console.log(memoizedNchoosek(5, 2));
console.log('Next call to `nchoosek` to use the cache.');
console.log(memoizedNchoosek(3, 1));
/*
First call to `factorial` to warm the cache.
Computing factorial for N=5
Computing factorial for N=4
Computing factorial for N=3
Computing factorial for N=2
Computing factorial for N=1
Computing factorial for N=0
120
Next call to `factorial` to use the cache.
Using the value from the cache for args=[4]
24
First call to `nchoosek` to warm the cache.
Computing nchoosek for N=5, K=2
Computing nchoosek for N=4, K=2
Computing nchoosek for N=3, K=2
Computing nchoosek for N=2, K=2
Computing nchoosek for N=2, K=1
Computing nchoosek for N=1, K=1
Computing nchoosek for N=1, K=0
Computing nchoosek for N=3, K=1
Using the value from the cache for args=[2,1]
Computing nchoosek for N=2, K=0
Computing nchoosek for N=4, K=1
Using the value from the cache for args=[3,1]
Computing nchoosek for N=3, K=0
10
Next call to `nchoosek` to use the cache.
Using the value from the cache for args=[3,1]
3
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment