summaryrefslogtreecommitdiff
path: root/sudoku.scm
diff options
context:
space:
mode:
Diffstat (limited to 'sudoku.scm')
-rw-r--r--sudoku.scm98
1 files changed, 58 insertions, 40 deletions
diff --git a/sudoku.scm b/sudoku.scm
index d759fa7..7b1743c 100644
--- a/sudoku.scm
+++ b/sudoku.scm
@@ -1,53 +1,71 @@
(use-modules
+ (srfi srfi-1)
(sat solver)
(sat helpers))
;; Board indices: column row value
(define board-size 9)
-(solve-sat
- (let ((board (make-array #f
- board-size
- board-size
- board-size)))
- (array-map! board make-sat-variable)
- ;; No row contains duplicate values
- (do ((row 0 (1+ row))) ((= row board-size))
- (do ((value 0 (1+ value))) ((= value board-size))
- (exactly-one-true
- (map
- (lambda (col)
- (array-ref board col row value))
- (iota board-size)))))
+(define (get-value board vals col row)
+ (1+
+ (find
+ (lambda (possible-value)
+ (array-ref vals
+ (array-ref board col row possible-value)))
+ (iota board-size))))
+
+
+(let ((board (make-array #f
+ board-size
+ board-size
+ board-size)))
+ (array-map! board make-sat-variable)
+
+ ;; No row contains duplicate values
+ (do ((row 0 (1+ row))) ((= row board-size))
+ (do ((value 0 (1+ value))) ((= value board-size))
+ (exactly-one-true
+ (map
+ (lambda (col)
+ (array-ref board col row value))
+ (iota board-size)))))
- ;; No column contains duplicate values
- (do ((col 0 (1+ col))) ((= col board-size))
+ ;; No column contains duplicate values
+ (do ((col 0 (1+ col))) ((= col board-size))
+ (do ((value 0 (1+ value))) ((= value board-size))
+ (exactly-one-true
+ (map
+ (lambda (row)
+ (array-ref board col row value))
+ (iota board-size)))))
+
+ ;; No 3x3 box contains duplicate values
+ (do ((col 0 (+ 3 col))) ((= col board-size))
+ (do ((row 0 (+ 3 row))) ((= row board-size))
(do ((value 0 (1+ value))) ((= value board-size))
(exactly-one-true
- (map
- (lambda (row)
- (array-ref board col row value))
- (iota board-size)))))
-
- ;; No 3x3 box contains duplicate values
- (do ((col 0 (+ 3 col))) ((= col board-size))
- (do ((row 0 (+ 3 row))) ((= row board-size))
- (do ((value 0 (1+ value))) (= value board-size)
- (exactly-one-true
- (let loop ((l '()))
- (do ((col1 0 (+ 3 col1))) ((= col1 3))
- (do ((row1 0 (+ 3 row1))) ((= row1 3))
- (loop (cons (array-ref board
+ (let ((l '()))
+ (do ((col1 0 (1+ col1))) ((= col1 3))
+ (do ((row1 0 (1+ row1))) ((= row1 3))
+ (set! l (cons (array-ref board
(+ col col1)
- (+ row row1))
- l)))))))))
+ (+ row row1)
+ value)
+ l))))
+ l)))))
- ;; Each position contains exactly one number
- (do ((col 0 (1+ col))) ((= col board-size))
- (do ((row 0 (1+ row))) ((= row board-size))
- (exactly-one-true
- (map
- (lambda (value)
- (array-ref board col row value))
- (iota board-size)))))))
+ ;; Each position contains exactly one number
+ (do ((col 0 (1+ col))) ((= col board-size))
+ (do ((row 0 (1+ row))) ((= row board-size))
+ (exactly-one-true
+ (map
+ (lambda (value)
+ (array-ref board col row value))
+ (iota board-size)))))
+
+ (let ((vals (solve-sat)))
+ (do ((row 0 (1+ row))) ((= row board-size))
+ (do ((col 0 (1+ col))) ((= col board-size))
+ (format #t "~a" (get-value board vals col row)))
+ (newline))))