X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/lisp/blobdiff_plain/0eed4749891adf0a7be89e786b8968ee805a8d41..77f935dafbb63f1674a3df832972fda67c10e3d6:/factorial.lisp diff --git a/factorial.lisp b/factorial.lisp index 3a76843..64c521e 100644 --- a/factorial.lisp +++ b/factorial.lisp @@ -22,28 +22,25 @@ ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. (defpackage #:mdw.factorial - (:use #:common-lisp) - (:export #:factorial)) + (:use #:common-lisp)) (in-package #:mdw.factorial) +(export 'factorial) (defun factorial (n) - "Compute a factorial. This is a little bit optimized: we try to multiply - values which are similar in size." + "Compute a factorial." + + ;; This is a little bit optimized: we try to multiply values which are + ;; similar in size. (when (minusp n) (error "negative factorial argument ~A" n)) - (let ((stack nil)) - (do ((i 2 (1+ i))) - ((> i n)) - (let ((f i)) - (loop - (unless stack (return)) - (let ((top (car stack))) - (when (< f top) (return)) - (setf f (* f top)) - (pop stack))) - (push f stack))) - (do ((stack stack (cdr stack)) - (a 1 (* a (car stack)))) - ((null stack) a)))) + (do ((i 2 (1+ i)) + (stack nil (do ((s stack (cdr s)) + (f i (* f (car s)))) + ((or (null s) (< f (car s))) + (cons f s))))) + ((> i n) + (do ((s stack (cdr s)) + (a 1 (* a (car s)))) + ((null s) a))))) ;;;----- That's all, folks --------------------------------------------------