implement memoization