From: smallpond on 19 Sep 2007 14:51 On Sep 19, 8:38 am, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote: > qikink wrote: > > On Sep 18, 9:18 pm, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote: > >> After a bit of effort, my first working lisp code which is slightly more > >> complex than printing "hello", it returns the nth fibonacci number. > >> How would you lisp gurus have written the code in the proper lisp way. > > <code> > > (defun fib (n) > > (cond > > ((= n 0) 1) > > ((= n 1) 1) > > (t (+ (fib (- n 1)) (fib (- n 2)))) > > ) > > ) > > </code> > > The above one hangs while computing (fib 200) It may be hung or it may be just pensive. Perhaps you could write a short program that tells whether it will eventually complete. -- S
From: Thomas A. Russ on 19 Sep 2007 16:27 "J. I. Gyasu" <j.i.gyasu(a)nospam> writes: > > In case you nitpick was about the count starting from 0. > > [1]> (defun fib (n) > (if (= n 0) (return-from fib 0)) > (let ( (f0 0) (f1 1) (counter 1) ) > (loop > (if (>= counter n) (return-from fib f1) ) > (let* ( (tmp f0) ) > (setf f0 f1) (setf f1 (+ f1 tmp)) (incf counter))))) A slightly more compact version, that uses a few more of Lisp's built-in functions: (defun fib (n) (if (zerop n) 0 (let ((f0 0) (f1 1)) (dotimes (i (1- n)) (psetq f0 f1 f1 (+ f1 f0))) f1))) -- Thomas A. Russ, USC/Information Sciences Institute
From: Giorgos Keramidas on 23 Sep 2007 19:50 On Wed, 19 Sep 2007 01:22:22 -0400, D Herring <dherring(a)at.tentpost.dot.com> wrote: > J. I. Gyasu wrote: >> After a bit of effort, my first working lisp code which is slightly >> more complex than printing "hello", it returns the nth fibonacci >> number. >> >> How would you lisp gurus have written the code in the proper lisp way. >> >> (defun fib (n) >> (let ( (f0 0) (f1 1) (counter 1) ) >> (loop >> (if (>= counter n) (return-from fib f1) ) >> (let* ( (tmp f0) ) >> (setf f0 f1) (setf f1 (+ f1 tmp)) (incf counter))))) Hi J.I., IMHO there are too many LET forms and RETURN-FROM seems a bit "Un-Lispy" indeed, but taste is a very personal thing, so if you like things this way, then who are we to judge your code by our personal definition of what is "tasteful" or "Lispy"? :-) > Do any of these follow the proper lisp way? > Probably not -- I'm not a guru. ;) Nice collection you have there! > (defun f (n) ...) > (defun g (n) ...) > (defun h (n) > (loop for x from 1 upto n > for a = 0 then b > and b = 1 then (+ a b) > finally (return b))) Since [1..n] has the same size as [0..(n-1)] this version looks very cool already, and "from 1 upto n" can be replaced with "below n": CL-USER> (defun fib (n) (loop for x below n for a = 0 then b and b = 1 then (+ a b) finally (return b))) CL-USER> (mapcar #'fib (loop for x from 1 upto 20 collecting x)) (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765) CL-USER> One version which I didn't see listed is the one using DO, which has the interesting property of numbering Fibonacci's starting from a 0th number instead of a 1st: CL-USER> (defun fib (num) (do ((a 0 b) (b 1 (+ a b)) (x 0 (incf x))) ((= x num) b) nil)) CL-USER> (mapcar #'fib (loop for x below 20 collecting x)) (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765) CL-USER> Then after staring at this for a while and re-ordering only a wee bit the LOOP-based version it is trivial to also write a LOOP-based version supporting a 0th Fibonnaci: CL-USER> (defun fib (num) (loop for a = 0 then b and b = 1 then (+ a b) for x below num finally (return b))) CL-USER> (mapcar #'fib (loop for x below 20 collecting x)) (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765) CL-USER> In general, I tend to avoid DO if I can help it, but in this case it helped me understand more about the way LOOP works, so _thanks_ for triggerring this with your initial collection :) - Giorgos
From: Giorgos Keramidas on 23 Sep 2007 19:56 On Wed, 19 Sep 2007 08:38:34 -0400, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote: > qikink wrote: >> On Sep 18, 9:18 pm, "J. I. Gyasu" <j.i.gyasu(a)nospam> wrote: >>> After a bit of effort, my first working lisp code which is slightly more >>> complex than printing "hello", it returns the nth fibonacci number. >>> How would you lisp gurus have written the code in the proper lisp way. >> <code> >> (defun fib (n) >> (cond >> ((= n 0) 1) >> ((= n 1) 1) >> (t (+ (fib (- n 1)) (fib (- n 2)))) >> ) >> ) >> </code> > > The above one hangs while computing (fib 200) Try tracing it and watch the recursions unfold in their magnificent glory :)
From: Giorgos Keramidas on 23 Sep 2007 20:23 On 19 Sep 2007 13:27:07 -0700, tar(a)sevak.isi.edu (Thomas A. Russ) wrote: > A slightly more compact version, that uses a few more of Lisp's > built-in functions: > > (defun fib (n) > (if (zerop n) > 0 > (let ((f0 0) (f1 1)) > (dotimes (i (1- n)) > (psetq f0 f1 > f1 (+ f1 f0))) > f1))) Nice, but somehow it doesn't feel right when it yields: CL-USER> (fib -10) 1 CL-USER> Tweaking it a bit by replacing (zerop n) with (< n 1), may be a good idea, but that's nit-picking now :)
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Ltk + Slime + Mac OSX 10.4 + (Clisp or SBCL or OpenMCL or CMUCL) Next: CLOS persistence |