I wrote:

> Making the following changes reduced the run time from 13.5 seconds
> to about 3 seconds.  I'm running under FreeBSD with a 1.1 Ghz
> Athlon.


A few more declarations got the running time down under 1 second:

----------------------------------------
(declaim (optimize (speed 3) (safety 1) (space 0)))

(declaim (fixnum *sides* *num*))
(defconstant *sides* 10)
(defconstant *num* 6)

(declaim (type (simple-array (unsigned-byte 16) (#.*sides*)) r))
(defvar r (make-array *sides* :element-type '(unsigned-byte 16))) 

(defun check (dice num succ fail botch)
  (declare (type (simple-array (unsigned-byte 16) (#.*num*)) dice)
           (type (simple-array (unsigned-byte 16) (#.*sides*)) succ fail botch))
  ;; reset counters
  (dotimes (i *sides*)
    (setf (aref r i) 0))
  ;; scan dices
  (let ((ones 0))
    (declare (fixnum ones))
    (dotimes (i num)
      (if (= (aref dice i) 0)
        (incf ones)
        (progn
          (loop for j of-type (unsigned-byte 16) from (aref dice i) downto 1
                do (incf (aref r j))))))
    ;; record results
    (dotimes (i *sides*)
      (cond
        ((> (aref r i) ones) (incf (aref succ i)))
        ((and (> ones 0) (= (aref r i) 0)) (incf (aref botch i)))
        (t (incf (aref fail i)))))))

(defun increment (dice num)
  (declare (fixnum num))
  (declare (type (simple-array (unsigned-byte 16) (#.*num*)) dice))
  (loop for i fixnum from 0 below num
        do (incf (aref dice i))
        when (>= (aref dice i) *sides*) do (setf (aref dice i) 0)
        else do (return-from increment nil)
        finally (return-from increment t)))


(defun test-it ()
  (let* ((num *num*)
         (dice  (make-array num :initial-element 0 :element-type '(unsigned-byte 16)))
         (succ  (make-array *sides* :initial-element 0 :element-type '(unsigned-byte 
16)))
         (fail  (make-array *sides* :initial-element 0 :element-type '(unsigned-byte 
16)))
         (botch (make-array *sides* :initial-element 0 :element-type '(unsigned-byte 
16))))
    (declare (fixnum num))
    (declare (type (simple-array (unsigned-byte 16) (#.*num*)) dice)
             (type (simple-array (unsigned-byte 16) (#.*sides*)) succ fail botch))
    (format t "Start...~%")
    (loop
     do (check dice num succ fail botch)
     until (increment dice num))
    (print succ)
    (print fail)
    (print botch)
    ))

----------------------------------------

-- 
Fred Gilham [EMAIL PROTECTED] || His word is a creative word, and
when he speaks the good exists as good.  God is neither arbitrary nor
tyrannical.  He is love, and when he expresses his will it is a will
of love.  Hence the good given by God is good for us.-- Jacques Ellul

Reply via email to