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

abaine at common-lisp.net abaine at common-lisp.net
Tue Aug 14 04:48:37 UTC 2007


Author: abaine
Date: Tue Aug 14 00:48:37 2007
New Revision: 135

Modified:
   trunk/funds/src/examples/sudoku.lisp
Log:
Start of a solver added.

Modified: trunk/funds/src/examples/sudoku.lisp
==============================================================================
--- trunk/funds/src/examples/sudoku.lisp	(original)
+++ trunk/funds/src/examples/sudoku.lisp	Tue Aug 14 00:48:37 2007
@@ -1,16 +1,144 @@
 
 (in-package :funds)
 
+(defconstant +false+ 0)
+(defconstant +true+ 1)
+(defconstant +unknown+ 2)
+
+(defun true-p (n) (= n +true+))
+(defun false-p (n) (= n +false+))
+(defun unknown-p (n) (= n +unknown+))
+(defun solved-p (n) (not (unknown-p n)))
+
+(defun range (size)
+  (case size 
+    (0 '())
+    (1 '(1))
+    (4 '(0 1 2 3))
+    (9 '(0 1 2 3 4 5 6 7 8))
+    (25 '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24))
+    (otherwise (loop for i below size collecting i))))
+
+(defstruct puzzle
+  size 
+  tree)
+
 (defun puzzle-from-list (list-rep)
   (let ((size (length list-rep)))
-    (make-f-array (expt size 3)
-		  :initial-contents (mapcan #'(lambda (row)
-						(mapcan #'(lambda (elt)
-							    (loop for i below size 
-								  collect (= i (1- elt))))
-							row))
-					    list-rep))))
-
-
-
-
+    (make-puzzle 
+     :size size
+     :tree
+     (make-f-array (expt size 3)
+		   :initial-contents 
+		   (mapcan #'(lambda (row)
+			       (mapcan #'(lambda (elt)
+					   (loop for i below size 
+						 collect (cond ((zerop elt) +unknown+)
+							       ((= i (1- elt)) +true+)
+							       (t +false+))))
+				       row))
+			   list-rep)))))
+
+(defun list-from-puzzle (puzzle)
+  (let ((size (puzzle-size puzzle)))
+    (loop for i below size collect 
+	  (loop for j below size collect
+		(loop for k below size
+		      when (true-p (puzzle-elt puzzle i j k))
+		      do (return (1+ k))
+		      finally (return 0))))))
+
+(defun puzzle-elt (puzzle row column number)
+  (f-array-elt (puzzle-tree puzzle) 
+	       (index-from-coordinates row column number (puzzle-size puzzle))))
+
+(defun puzzle-complete (puzzle)
+  (let ((size (puzzle-size puzzle)))
+    (loop for i below size always
+	  (loop for j below size always
+		(loop for k below size always
+		      (not (unknown-p (puzzle-elt puzzle i j k))))))))
+
+(defun set-to-true (puzzle i j k)
+  (fill-falses (make-puzzle :size (puzzle-size puzzle)
+			    :tree (tree-insert (puzzle-tree puzzle)
+					       (index-from-coordinates 
+						i j k
+						(puzzle-size puzzle))
+					       +true+))
+	       i j k))
+
+(defun set-to-false (puzzle i j k)
+  (let ((size (puzzle-size puzzle)))
+    (make-puzzle :size size
+		 :tree (tree-insert (puzzle-tree puzzle)
+				    (index-from-coordinates i j k)
+				    +false+))))
+
+(defun fill-falses (puzzle i j k)
+  (let ((size (puzzle-size puzzle)))
+    (make-puzzle :size size 
+		 :tree (reduce #'(lambda (tree index)
+				   (reduce #'(lambda (tr x)
+					       (if (unknown-p (tree-find tr x))
+						   (tree-insert tr x +false+)
+						   tr))
+					   (list (index-from-coordinates i j index size)
+						 (index-from-coordinates i index k size)
+						 (index-from-coordinates index j k size)
+						 (index-from-coordinates
+						  (calc-i i j index size)
+						  (calc-j i j index size)
+						  k size))
+					   :initial-value tree))
+			       (range size)
+			       :initial-value (puzzle-tree puzzle)))))
+
+(defun calc-i (i j index size)
+  (let ((order (order size)))
+    (+ (start i order)
+       (floor index order))))
+
+(defun calc-j (i j index size)
+  (let ((order (order size)))
+    (+ (start j order)
+     (mod index order))))
+
+
+(defun start (x order)
+  (* order (floor x order)))
+
+(defun order (size)
+  (round (sqrt size)))
+
+(defun index-from-coordinates (i j k size)
+  (+ (* i size size)
+     (* j size)
+     k))
+
+(defun complete-p (puzzle)
+  (labels ((f (tree)
+	     (or (tree-empty-p tree)
+		 (and (solved-p (bt-value tree))
+		      (f (bt-left tree))
+		      (f (bt-right tree))))))
+    (f (puzzle-tree puzzle))))
+
+(defun solvable-p (puzzle)
+  (let ((size (puzzle-size puzzle)))
+    (loop for i below size always
+	  (loop for j below size always
+		(not (or (loop for k below size always (false-p (puzzle-elt puzzle i j k)))		       
+			 (loop for k below size always (false-p (puzzle-elt puzzle i k j)))
+			 (loop for k below size always (false-p (puzzle-elt puzzle k i j)))
+			 (loop for k below size always 
+			       (false-p (puzzle-elt-by-box puzzle i j k)))))))))
+
+(defun puzzle-elt-by-box (puzzle number box index)
+  (let ((order (order (puzzle-size puzzle))))
+    (puzzle-elt puzzle 
+		(+ (* order (floor box order))
+		   (floor index order))
+		(+ (* order (mod box order))
+		   (mod index order))
+		number)))



More information about the Funds-cvs mailing list