diff --git a/Cache/Memoize.js b/Cache/Memoize.js new file mode 100644 index 0000000000..9bd998fdac --- /dev/null +++ b/Cache/Memoize.js @@ -0,0 +1,42 @@ +/** + * Memoize + * + * From [Wikipedia](https://en.wikipedia.org/wiki/Memoization), + * memoization is an optimization technique + * used primarily to speed up computer programs, + * by storing the results of expensive function calls + * and returning the cached result when the same inputs occur again + * + * This function is a first class objects, + * which lets us use it as [Higher-Order Function](https://eloquentjavascript.net/05_higher_order.html) + * and return another function + * + * @param {Function} func Original function + * @returns {Function} Memoized function + */ +export const memoize = (func) => { + // Initialization of a slot to store the function result + const cache = {} + + return (...args) => { + // Retrieving the first argument of the function + const [arg] = args + + /** + * Checks if the argument is already present in the cache, + * then return the associated value / result + */ + if (arg in cache) { + return cache[arg] + } + + /** + * If the argument is not yet present in the cache, + * execute original function and save its value / result in cache, + * finally return it + */ + const result = func(arg) + cache[arg] = result + return result + } +} diff --git a/Cache/test/Memoize.test.js b/Cache/test/Memoize.test.js new file mode 100644 index 0000000000..4d156ce347 --- /dev/null +++ b/Cache/test/Memoize.test.js @@ -0,0 +1,37 @@ +import { memoize } from '../Memoize' + +const fibonacci = (n) => { + if (n < 2) { + return n + } + + return fibonacci(n - 2) + fibonacci(n - 1) +} + +const factorial = (n) => { + if (n === 0) { + return 1 + } + + return n * factorial(n - 1) +} + +describe('Memoize', () => { + it('expects the fibonacci function to use the cache on the second call', () => { + const memoFibonacci = memoize(fibonacci) + + expect(memoFibonacci(5)).toEqual(fibonacci(5)) + expect(memoFibonacci(5)).toEqual(5) + expect(memoFibonacci(10)).toEqual(fibonacci(10)) + expect(memoFibonacci(10)).toEqual(55) + }) + + it('expects the factorial function to use the cache on the second call', () => { + const memoFactorial = memoize(factorial) + + expect(memoFactorial(5)).toEqual(factorial(5)) + expect(memoFactorial(5)).toEqual(120) + expect(memoFactorial(10)).toEqual(factorial(10)) + expect(memoFactorial(10)).toEqual(3628800) + }) +})