The lisp-way to solve Fibonnaci

前端 未结 14 1484
别那么骄傲
别那么骄傲 2021-02-08 07:17

I wanted to try and learn Lisp, but I very quickly gave up. I figured I\'d try again. I\'m looking at Problem 2 on Project Euler - finding the sum of all even Fibonacci numbers

14条回答
  •  遇见更好的自我
    2021-02-08 08:09

    Here is a memoised version. In this case, since you have to compute each fibonacci number until you find one more than four million, using closed form solutions would no do much good.

    This approach creates a lexical environment via let; create a dictionary fib-table and a function fib-memoed in that environment. The end product of this is fib-table is accesible from fib-memoed but no where else.

    Now the kicker: since we have to compute fib for sequential values until some condition is met, we start the solver at fib 1. From here on, computing the next fib number entails at most 2 dictionary lookups and one addition: O(1) BOOM!

    ;; memoised fib function: make a hash table, then create                                      
    ;; the fib function in the lexical scope of the hash table                                    
    (let ((fib-table (make-hash-table)))
      (setf (gethash 0 fib-table) 1)
      (setf (gethash 1 fib-table) 1)
      (defun fib-memoed (n)
        (let ((x (gethash n fib-table)))
          (cond ((not (null x))
                 x)
                (t
                 (let ((y (+ (fib-memoed (- n 1))
                             (fib-memoed (- n 2)))))
                   (setf (gethash n fib-table) y)
                   y))))))
    
    (defun solve ()
      (let ((maxval 4000000))
        (labels ((aux (i acc)
                   (let ((x (fib-memoed i)))
                     (cond ((> x maxval) acc)
                           ((evenp x)
                            (aux (1+ i) (+ x acc)))
                           (t (aux (1+ i) acc))))))
          (aux 1 0))))
    

提交回复
热议问题