[funds-cvs] r144 - trunk/funds/src/examples

abaine at common-lisp.net abaine at common-lisp.net
Sun Aug 19 00:19:02 UTC 2007


Author: abaine
Date: Sat Aug 18 20:19:01 2007
New Revision: 144

Modified:
   trunk/funds/src/examples/sudoku.lisp
Log:
Solver's getting good.

Modified: trunk/funds/src/examples/sudoku.lisp
==============================================================================
--- trunk/funds/src/examples/sudoku.lisp	(original)
+++ trunk/funds/src/examples/sudoku.lisp	Sat Aug 18 20:19:01 2007
@@ -122,40 +122,19 @@
       (if (solved-p puzzle)
 	  puzzle
 	  nil)
-      (iter (for f in (list #'best-row
-			 #'best-column
-			 #'best-number
-			 #'best-box))
-	 (for s in (list #'solve-row
-			 #'solve-column
-			 #'solve-number
-			 #'solve-box))
-	 (for (values x y n) = (funcall f puzzle))
-	 (finding x minimizing n into best-x)
-	 (finding y minimizing n into best-y)
-	 (finding s minimizing n into (best-s min))
-	 (when (= min 1)
-	   (return (funcall best-s puzzle best-x best-y)))
-	 (finally (return (funcall best-s puzzle best-x best-y))))))
-
-(defun best-row (puzzle)
-  (best-group puzzle #'row-freedom))
-
-(defun best-column (puzzle)
-  (best-group puzzle #'column-freedom))
+      (iter (for f in x-y-z-functions)
+	    (for (values x y n) = (best-group puzzle f))
+	    (finding (list f x y) minimizing n into (best-list min))
+	    (when (= min 1)
+	      (return (apply #'solve-group puzzle best-list)))
+	    (finally (return (apply #'solve-group puzzle best-list))))))
 
-(defun best-number (puzzle)
-  (best-group puzzle #'number-freedom))
-
-(defun best-box (puzzle)
-  (best-group puzzle #'box-freedom))
-
-(defun best-group (puzzle freedom-function)
+(defun best-group (puzzle x-y-z-function)
   (let ((size (puzzle-size puzzle)))
     (iter (for x below size)
 	  (for (values y n) = 
 	       (iter (for y below size)
-		     (for n = (funcall freedom-function puzzle x y))
+		     (for n = (group-freedom puzzle x-y-z-function x y))
 		     (finding y minimizing n into (best-y min))
 		     (when (= min 1)
 		       (return (values best-y min)))
@@ -166,65 +145,19 @@
 	    (return (values best-x best-y best-n)))
 	  (finally (return (values best-x best-y best-n))))))
 
-(defun row-freedom (puzzle i k)
-  (let ((size (puzzle-size puzzle)))
-    (iter (for j below size)
-	  (counting (elt-unknown-p (puzzle-elt puzzle i j k)) into c)
-	  (finally (return (enlarge-zero c size) )))))
-
-
-
-
-(defun column-freedom (puzzle j k)
-  (let ((size (puzzle-size puzzle)))
-    (iter (for i below size)
-	  (counting (elt-unknown-p (puzzle-elt puzzle i j k)) into c)
-	  (finally (return (enlarge-zero c size))))))
-
-
-
-(defun number-freedom (puzzle i j)
-  (let ((size (puzzle-size puzzle)))
-    (iter (for k below size)
-	  (counting (elt-unknown-p (puzzle-elt puzzle i j k)) into c)
-	  (finally (return (enlarge-zero c size))))))
-
-(defun box-freedom (puzzle b k)
-  (let* ((size (puzzle-size puzzle))
-	 (order (order size)))
-    (iter (for x below size)
-	  (counting (elt-unknown-p (puzzle-elt puzzle 
-					       (+ (* order (floor b order))
-						  (floor x order))
-					       (+ (* order (mod b order))
-						  (mod x order))
-					       k))
-		    into c)
-	  (finally (return (enlarge-zero c size))))))
-
 (defun group-freedom (puzzle x-y-z-function x y)
   (let ((size (puzzle-size puzzle)))
-    (iter (for z below size)
-	  (counting (elt-unknown-p (multiple-value-call #'puzzle-elt puzzle
-							(funcall x-y-z-function x y z size)))))))
+    (enlarge-zero
+     (iter (for z below size)
+	   (counting (elt-unknown-p (multiple-value-call #'puzzle-elt puzzle
+							 (funcall x-y-z-function x y z size)))))
+     size)))
 
 (defun enlarge-zero (count size)
   (if (zerop count)
       (1+ size)
       count))
 
-(defun solve-row (puzzle i k)
-  (solve-group puzzle #'i-k-j-coordinates i k))
-
-(defun solve-column (puzzle j k)
-  (solve-group puzzle #'j-k-i-coordinates j k))
-
-(defun solve-number (puzzle i j)
-  (solve-group puzzle #'i-j-k-coordinates i j))
-
-(defun solve-box (puzzle b k)
-  (solve-group puzzle #'b-k-x-coordinates b k))
-
 (defun solve-group (puzzle x-y-z-function x y)
   (let ((size (puzzle-size puzzle)))  
     (labels ((f (z)
@@ -246,12 +179,8 @@
   (let ((size (puzzle-size puzzle))) 
     (iter (for x below size)
 	 (always (iter (for y below size)
-		       (always (iter (for x-y-z-function in (list 
-							 #'i-j-k-coordinates
-							 #'i-k-j-coordinates
-							 #'j-k-i-coordinates
-							 #'b-k-x-coordinates))
-				     (always (group-solved puzzle x-y-z-function x y)))))))))
+		       (always (iter (for f in x-y-z-functions)
+				     (always (group-solved puzzle f x y)))))))))
 
 (defun i-j-k-coordinates (i j k size)
   (declare (ignore size))
@@ -279,3 +208,23 @@
 	       (count (elt-true-p (multiple-value-call
 				      #'puzzle-elt puzzle
 				      (funcall x-y-z-function x y z size))))))))
+
+(defun puzzle-solvable (puzzle)
+  (let ((size (puzzle-size puzzle)))
+    (iter (for f in x-y-z-functions)
+	  (always (iter (for x below size)
+			(always (iter (for y below size)
+				      (always (group-solvable puzzle f x y)))))))))
+
+(defun group-solvable (puzzle x-y-z-function x y)
+  (let ((size (puzzle-size puzzle)))
+    (iter (for z below size)
+	  (for elt = (multiple-value-call #'puzzle-elt
+		       puzzle (funcall x-y-z-function x y z size)))
+	  (thereis (or (elt-unknown-p elt)
+		       (elt-true-p elt))))))
+
+(defvar x-y-z-functions (list #'i-j-k-coordinates
+			      #'i-k-j-coordinates
+			      #'j-k-i-coordinates
+			      #'b-k-x-coordinates))



More information about the Funds-cvs mailing list