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
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))))