diff options
Diffstat (limited to 'sudoku.scm')
-rw-r--r-- | sudoku.scm | 98 |
1 files changed, 58 insertions, 40 deletions
@@ -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)))) |