{"id":77,"date":"2016-02-05T23:25:55","date_gmt":"2016-02-06T05:25:55","guid":{"rendered":"http:\/\/www.playwithlua.com\/?p=77"},"modified":"2016-02-05T23:25:55","modified_gmt":"2016-02-06T05:25:55","slug":"fun-with-fibonacci","status":"publish","type":"post","link":"http:\/\/www.playwithlua.com\/?p=77","title":{"rendered":"Fun with Fibonacci"},"content":{"rendered":"<p>Or, how to annihilate an interview question. I was asked this a little over a year ago in an interview, and I&#8217;d been asked it a few times before then too; it&#8217;s pretty common.<\/p>\n<p>&#8220;Write a function that takes a parameter n and returns the nth Fibonacci number.&#8221; The Fibonacci sequence, if you don&#8217;t already know, is defined like this: f(1) and f(2) are both 1. After that, each number in the sequence is the sum of the previous two, so, f(3) is 2 (because 1+1), then f(4) is 3, then f(5) is 5, and so on.<\/p>\n<p><!--more--><\/p>\n<p>(Fun, useless fact: this was originally discovered as part of a thought experiment about rabbits. If you imagine that you start with two rabbits, and each month each rabbit produces another rabbit (but rabbits don&#8217;t reproduce until they&#8217;re one month old), then the rabbit population after n months is the nth Fibonacci number.)<\/p>\n<h2>Naive version<\/h2>\n<p>So, start off by writing the naive recursive version:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> fib<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> n <span style=\"color: #66cc66;\">&lt;<\/span> <span style=\"color: #cc66cc;\">3<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span> <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> <span style=\"color: #cc66cc;\">1<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">else<\/span> <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> fib<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #66cc66;\">+<\/span> fib<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>This works, but it&#8217;s inefficient: if you call it with n=4, say, it results in 5 calls: 4, 3, 2, 1, and 2. Calling it with n=8 is 21 calls. In fact, it&#8217;s actually O(fib(n)) complexity; the number of recursive calls rises at the same rate as the Fibonacci sequence itself.<\/p>\n<p>So let&#8217;s make it faster.<\/p>\n<h2>Iterative version<\/h2>\n<p>One way is to make it iterative:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> ifib<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> a<span style=\"color: #66cc66;\">,<\/span>b <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">1<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">for<\/span> k <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #cc66cc;\">3<\/span><span style=\"color: #66cc66;\">,<\/span>n <span style=\"color: #aa9900; font-weight: bold;\">do<\/span>\n        a<span style=\"color: #66cc66;\">,<\/span> b <span style=\"color: #66cc66;\">=<\/span> b<span style=\"color: #66cc66;\">,<\/span> a<span style=\"color: #66cc66;\">+<\/span>b\n    <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> b\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now it won&#8217;t recurse at all, of course, but it&#8217;s kind of ugly. Recursion is cool, iteration is boring. Let&#8217;s try to make the recursive one more efficient.<\/p>\n<h2>Memoized version<\/h2>\n<p>If you look at the naive version, it&#8217;s calling itself with the same argument several times. We can help matters by caching the results so after it calls once it never has to again:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> memoize<span style=\"color: #66cc66;\">&#40;<\/span>fn<span style=\"color: #66cc66;\">&#41;<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> cache <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#123;<\/span><span style=\"color: #66cc66;\">&#125;<\/span>\n&nbsp;\n    <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> <span style=\"color: #aa9900; font-weight: bold;\">function<\/span><span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n        cache<span style=\"color: #66cc66;\">&#91;<\/span>n<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #66cc66;\">=<\/span> cache<span style=\"color: #66cc66;\">&#91;<\/span>n<span style=\"color: #66cc66;\">&#93;<\/span> <span style=\"color: #aa9900; font-weight: bold;\">or<\/span> fn<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n        <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> cache<span style=\"color: #66cc66;\">&#91;<\/span>n<span style=\"color: #66cc66;\">&#93;<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\nfib <span style=\"color: #66cc66;\">=<\/span> memoize<span style=\"color: #66cc66;\">&#40;<\/span>fib<span style=\"color: #66cc66;\">&#41;<\/span><\/pre><\/div><\/div><\/div>\n\n<p>Now when you call it with n=4, say, you only get 4 recursive calls: 4, 3, 2, and 1. In general it will call itself n times, because if it ever has to repeat a call it&#8217;ll use the cache. So now it&#8217;s O(n).<\/p>\n<p>But that&#8217;s not perfect. We&#8217;re still using a lot of stack space. It would be nicer if it ran in constant stack space.<\/p>\n<h2>Tail-recursive version<\/h2>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\"><span style=\"color: #aa9900; font-weight: bold;\">function<\/span> tfib<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">local<\/span> <span style=\"color: #aa9900; font-weight: bold;\">function<\/span> f<span style=\"color: #66cc66;\">&#40;<\/span>a<span style=\"color: #66cc66;\">,<\/span> b<span style=\"color: #66cc66;\">,<\/span> n<span style=\"color: #66cc66;\">&#41;<\/span>\n        <span style=\"color: #aa9900; font-weight: bold;\">if<\/span> n <span style=\"color: #66cc66;\">&lt;<\/span> <span style=\"color: #cc66cc;\">3<\/span> <span style=\"color: #aa9900; font-weight: bold;\">then<\/span>\n            <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> b\n        <span style=\"color: #aa9900; font-weight: bold;\">else<\/span>\n            <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> f<span style=\"color: #66cc66;\">&#40;<\/span>b<span style=\"color: #66cc66;\">,<\/span> a<span style=\"color: #66cc66;\">+<\/span>b<span style=\"color: #66cc66;\">,<\/span> n<span style=\"color: #66cc66;\">-<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n        <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">end<\/span>\n&nbsp;\n    <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> f<span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">,<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">,<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>You can see this is a lot like the iterative version: we&#8217;re starting from the first two values and working up, and shifting (a+b)-to-b and b-to-a each time. But the mechanism of looping is recursion, and the recursive call is the last thing that happens in any given invocation, so, it&#8217;s tail recursive and Lua can eliminate the tail call so it never blows out the stack.<\/p>\n<p>At this point we&#8217;ve got a naive, easy-to-read version; a version that&#8217;s fast and small but ugly; a version that&#8217;s fast and pretty but needs memory for a cache; and a version that&#8217;s fast and pretty and uses constant memory. The only way to improve it further is to be clever:<\/p>\n<h2>The closed-form version<\/h2>\n<p>The first three new versions we made are general transformations useful for speeding up any slow function. This one is specific to the Fibonacci function. It turns out that as n approaches infinity, the ratio of fib(n) to fib(n-1) is phi, the golden ratio.<\/p>\n<p>Phi is <code>(1 + math.sqrt(5)) \/ 2<\/code>. The closest integer to <code>phi^n \/ math.sqrt(5)<\/code> is the nth Fibonacci number, and we can easily find that with <code>math.floor<\/code>:<\/p>\n\n<div class=\"my_syntax_box\"><div class=\"my_syntax\"><div class=\"code\"><pre class=\"lua\" style=\"font-family:monospace;\">phi <span style=\"color: #66cc66;\">=<\/span> <span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">+<\/span><span style=\"color: #0000aa;\">math.sqrt<\/span><span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">5<\/span><span style=\"color: #66cc66;\">&#41;<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #66cc66;\">\/<\/span> <span style=\"color: #cc66cc;\">2<\/span>\n&nbsp;\n<span style=\"color: #aa9900; font-weight: bold;\">function<\/span> fib<span style=\"color: #66cc66;\">&#40;<\/span>n<span style=\"color: #66cc66;\">&#41;<\/span>\n    <span style=\"color: #aa9900; font-weight: bold;\">return<\/span> <span style=\"color: #0000aa;\">math.floor<\/span><span style=\"color: #66cc66;\">&#40;<\/span>phi<span style=\"color: #66cc66;\">^<\/span>n <span style=\"color: #66cc66;\">\/<\/span> <span style=\"color: #0000aa;\">math.sqrt<\/span><span style=\"color: #66cc66;\">&#40;<\/span><span style=\"color: #cc66cc;\">5<\/span><span style=\"color: #66cc66;\">&#41;<\/span> <span style=\"color: #66cc66;\">+<\/span> <span style=\"color: #cc66cc;\">1<\/span><span style=\"color: #66cc66;\">\/<\/span><span style=\"color: #cc66cc;\">2<\/span><span style=\"color: #66cc66;\">&#41;<\/span>\n<span style=\"color: #aa9900; font-weight: bold;\">end<\/span><\/pre><\/div><\/div><\/div>\n\n<p>It doesn&#8217;t get much better than this: constant time and constant space. Beyond this there&#8217;s not a lot you can do to make it more efficient.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Or, how to annihilate an interview question. I was asked this a little over a year ago in an interview, and I&#8217;d been asked it a few times before then too; it&#8217;s pretty common. &#8220;Write a function that takes a parameter n and returns the nth Fibonacci number.&#8221; The Fibonacci sequence, if you don&#8217;t already [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts\/77"}],"collection":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=77"}],"version-history":[{"count":0,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=\/wp\/v2\/posts\/77\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.playwithlua.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}