From 5f4da018672624b28d761c1b35015a98b19653ad Mon Sep 17 00:00:00 2001 From: "Peter S. Housel" <housel@acm.org> Date: Tue, 18 Feb 2020 21:20:06 -0800 Subject: [PATCH] gabriel: Fix the puzzle benchmark According to the comments from Henry Baker and the papers referenced from his page, the puzzle benchmark is supposed to arrive at a solution in 2005 trials (as measured by *kount*). Due to off-by-one and logic errors converting DO to DOTIMES, among other problems, the code arrived at an incorrect solution in many fewer trials than are actually necessary. --- files/gabriel.lisp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/files/gabriel.lisp b/files/gabriel.lisp index e00d661..d5c2f3c 100644 --- a/files/gabriel.lisp +++ b/files/gabriel.lisp @@ -1424,22 +1424,25 @@ (defun fit (i j) (declare (fixnum i j)) - (dotimes (k (svref *piecemax* i)) + (dotimes (k (1+ (svref *piecemax* i)) t) + (declare (type fixnum k)) (and (aref *puzzle-p* i k) - (svref *puzzle* (+ j k)) - (return nil))) - t) + (svref *puzzle* (the fixnum (+ j k))) + (return nil)))) (defun place (i j) (declare (fixnum i j)) (let ((end (svref *piecemax* i))) - (declare (fixnum end)) - (dotimes (k end) - (when (aref *puzzle-p* i k) - (setf (svref *puzzle* (+ j k)) t))) - (setf (svref *piece-count* (svref *class* i)) - (the fixnum (- (the fixnum (svref *piece-count* (svref *class* i))) 1))) - (do ((k j (1+ k))) + (declare (type fixnum end)) + (dotimes (k (1+ end)) + (declare (type fixnum k)) + (cond ((aref *puzzle-p* i k) + (setf (svref *puzzle* (the fixnum (+ j k))) t)))) + (setf (aref *piece-count* (aref *class* i)) + (the fixnum + (- (the fixnum + (aref *piece-count* (aref *class* i))) 1))) + (do ((k j (the fixnum (1+ k)))) ((> k +puzzle-size+) ; (terpri) ; (princ "Puzzle filled") @@ -1454,10 +1457,10 @@ (do ((k 0 (1+ k))) ((> k end)) (when (aref *puzzle-p* i k) - (setf (svref *puzzle* (+ j k)) nil)) - (setf (svref *piece-count* (svref *class* i)) - (the fixnum (+ (the fixnum (svref *piece-count* (svref *class* i))) - 1)))))) + (setf (svref *puzzle* (+ j k)) nil))) + (setf (svref *piece-count* (svref *class* i)) + (the fixnum (+ (the fixnum (svref *piece-count* (svref *class* i))) + 1))))) (defun trial (j) (declare (fixnum j)) @@ -1546,7 +1549,7 @@ (cond ((fit 0 m) (setq n (place 0 m))) (t (format t "~%Error."))) (cond ((trial n) - ;; (format t "~%Success in ~4D trials." kount) + ;; (format t "~%Success in ~4D trials." *kount*) ) (t (format t "~%Failure."))))) -- GitLab