diff --git a/src/functions_exercises.md b/src/functions_exercises.md index 8b2b81d..0f42a83 100644 --- a/src/functions_exercises.md +++ b/src/functions_exercises.md @@ -12,6 +12,22 @@ For testing you can `assert fib(8) == 21;`. +
+ Solution + + ```spicy + function fib(n: uint64): uint64 { + if (n < 2) + return n; + + # This runs iff above `if` condition was false, but in this case could also be written + # as an `else` branch. + return fib(n - 1) + fib(n - 2); + } + ``` + +
+ 1. Add memoization to your `fib` function. For that change its signature to ```spicy @@ -27,5 +43,51 @@ For testing you can `assert fib(64, m_fib) == 10610209857723;`. +
+ Solution + + ```spicy + function fib(n: uint64, inout cache: map): uint64 { + # If the value is already in the cache we do not need to compute it. + if (n in cache) + return cache[n]; + + # Value was not in the cache. Compute its value and store it. + local result = 0; + + if (n < 2) + result = n; + + else + # Here we want an `else` branch for sure. We need to pass the cache + # down to other invocations. Since the passing happens by reference all + # invocations share a cache. + result = fib(n - 1, cache) + fib(n - 2, cache); + + # Persist result in cache. + cache[n] = result; + + # Return the result. + return result; + } + ``` + +
+ 1. Try modifying your `fib` functions so users do not have to provide the cache themselves. + +
+ Hint + + You want to store the cache somewhere yourself and provide users with a + wrapped function which implicitly uses your cache. + + There are two places to put the cache: + + - Construct the cache as a local variable inside the body of your wrapper + function. With this different invocations of the wrapper function would + not share the same cache which can be useful in certain scenarios. + - Alternatively one could store the cache in a `global`. + +