Skip to content

Instantly share code, notes, and snippets.

@r00k
Created January 28, 2013 18:50
Show Gist options
  • Save r00k/4658025 to your computer and use it in GitHub Desktop.
Save r00k/4658025 to your computer and use it in GitHub Desktop.
Kinda mind-blowing fibonacci-sequence-producing function.
(defn fib [n]
(take n (map first (iterate (fn [[a b]] [b (+ a b)]) [1 1]))))
(fib 5) => (1 1 2 3 5)
@fogus
Copy link

fogus commented Jan 28, 2013

The beauty of the solution:

(def fibs (map first (iterate (fn [[a b]] [b (+ a b)]) [0N 1N])))

is that the Fibonacci numbers are a sequence of all of the Fibonacci numbers rather than some function that calculates the nth Fibonacci number. Therefore, the way to interact with fibs is to just reach in and get what you want:

(first fibs)
;;=> 0

(nth fibs 100)
;;=> 354224848179261915075N

(nth fib 1000)
43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875N

If you again want to get the value of the 100th Fibonacci number then just grab it again, Clojure will not calculate it again. I Fibonacci function is kinda cool, but all of the Fibonacci numbers is way cooler.

@mollymorphic
Copy link

You can do something similar in JS though it's not as pretty:

function allfibs(end) {
    var x = 0, y = 1, count = 1;
    yield 1;
    while (count++ < end) {
        [x,y] = [y,x + y];
        yield y;
    }
}

function fibs(x) {
    return [ i for (i in allfibs(x)) ]
}

fibs(5) // [1,1,2,3,5]

Wouldn't be hard to write some library functions like take() to get the nth element etc.

@r00k
Copy link
Author

r00k commented Jan 29, 2013

@lmarinho - I'd been playing there all morning actually. Thanks for the rec though!

@fogus - Totally agreed. As you covered in your book (which I'm loving), there's something beautifully declarative about saying "this is how you calculate ALL fibs", and then just taking what you need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment