Advertisement
bsddeamon

samdoku.scm

Mar 31st, 2016
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scheme 4.76 KB | None | 0 0
  1. ;; Samdoku modular rewrite for generator integration
  2.  
  3. (define-library (sudoku solver)
  4.   (import (scheme base)
  5.     (only (srfi 1) iota))
  6.   (export solve)
  7.   (begin
  8.  
  9. #| Resetting indentation here.
  10.     Come on I'm on my phone...
  11. |#
  12.  
  13. (define (list->rows ls)
  14.   (let f ([i 0] [j 0] [ls ls] [is '()] [js '()] [ks '()])
  15.     (cond [(> j 8) (f (+ i 1) 0 ls is js ks)]
  16.       [(> i 8) (map reverse (list is js ks))]
  17.       [else
  18.        (let ([k (car ls)])
  19.          (if (> k 0)
  20.              (f i (+ j 1) (cdr ls) (cons i is)
  21.                (cons j js) (cons (- k 1) ks))
  22.              (f i (+ j 1) (cdr ls)
  23.                (append (make-list 9 i) is)
  24.                (append (make-list 9 j) js)
  25.                (append (iota 9 8 -1) ks))))])))
  26.  
  27. ;; Matrix constructors
  28. (define-record-type <node>
  29.   (node h l u i j k r d s) #f
  30.   (h header set-header!) (l left set-left!)
  31.   (u up set-up!) (i ival) (j jval) (k kval)
  32.   (r right set-right!) (d down set-down!)
  33.   (s size set-size!))
  34.  
  35. (define (update-size! f x)
  36.   (let ([h (header x)])
  37.     (set-size! h (f (size h) 1))))
  38.  
  39. (define (horizontal-restore! x)
  40.   (set-right! (left x) x) (set-left! (right x) x))
  41.  
  42. (define (vertical-restore! x)
  43.   (update-size! + x)
  44.   (set-down! (up x) x)
  45.   (set-up! (down x) x))
  46.  
  47. (define (horizontal-delete! x)
  48.   (set-right! (left x) (right x))
  49.   (set-left! (right x) (left x)))
  50.  
  51. (define (vertical-delete! x)
  52.   (set-down! (up x) (down x))
  53.   (set-up! (down x) (up x))
  54.   (update-size! - x))
  55.  
  56. ;; Make (horizontal) headers.
  57. (define grid
  58.   (let ([g (node #f #f #f #f #f #f #f #f #f)])
  59.     (set-left! g g) (set-right! g g)
  60.     (do ([i 0 (+ i 1)]) ((> i 3))
  61.       (do ([j 0 (+ j 1)]) ((> j 8))
  62.         (do ([k 0 (+ k 1)]) ((> k 8))
  63.           (let ([h (node #f (left g) #f i j k
  64.                        g #f 0)]) (set-header! h h)
  65.             (set-up! h h) (set-down! h h)
  66.             (horizontal-restore! h))))) g))
  67.  
  68. #| Map constraints (matrix columns)
  69.     over possibilities (matrix rows).
  70. |#
  71. (define (make-row! r c v) (define i 0)
  72.   (define z (make-vector 4 #f))
  73.   (define constraints
  74.     (vector
  75.       (lambda (j k) (and (= j r) (= k c)))
  76.       (lambda (j k) (and (= j r) (= k v)))
  77.       (lambda (j k) (and (= j c) (= k v)))
  78.       (lambda (j k)
  79.         (and (= k v)
  80.           (= j (+ (* (floor-quotient r 3) 3)
  81.                   (floor-quotient c 3)))))))
  82.   (do ([h (right grid) (right h)])
  83.         ((vector-ref z 3) (vector->list z))
  84.     (and (= (ival h) i)
  85.       ((vector-ref constraints i)
  86.         (jval h) (kval h))
  87.       (vector-set! z i
  88.         (let ([x (node h #f (up h)
  89.                      r c v #f h #f)])
  90.           (vertical-restore! x) x))
  91.       (set! i (+ i 1)))))
  92.  
  93. (define (make-grid ls)
  94.   (apply for-each
  95.     (lambda (r c v)
  96.       (apply
  97.         (lambda (r-c r-v c-v b-v)
  98.           (set-left! r-c b-v)
  99.           (set-right! r-c r-v)
  100.           (set-left! r-v r-c)
  101.           (set-right! r-v c-v)
  102.           (set-left! c-v r-v)
  103.           (set-right! c-v b-v)
  104.           (set-left! b-v c-v)
  105.           (set-right! b-v r-c))
  106.         (make-row! r c v))) (list->rows ls)))
  107.  
  108. #| Matrix modifiers for backtracking
  109.     algorithm (they try).
  110. |#
  111. (define (vertical-cover! h)
  112.   (do ([r (down h) (down r)]) ((eq? r h))
  113.     (do ([c (right r) (right c)]) ((eq? c r))
  114.       (vertical-delete! c)))
  115.   (horizontal-delete! h))
  116.  
  117. (define (vertical-uncover! h)
  118.   (do ([r (up h) (up r)]) ((eq? r h))
  119.     (do ([c (right r) (right c)]) ((eq? c r))
  120.       (vertical-restore! c)))
  121.   (horizontal-restore! h))
  122.  
  123. (define (horizontal-cover! x)
  124.   (do ([c (right x) (right c)]) ((eq? c x))
  125.     (vertical-cover! (header c))))
  126.  
  127. (define (horizontal-uncover! x)
  128.   (do ([c (left x) (left c)]) ((eq? c x))
  129.     (vertical-uncover! (header c))))
  130.  
  131. (define (optimal-branch h)
  132.   (do ([c (right h) (right c)]
  133.          [m (right h)
  134.           (if (< (size c) (size m)) c m)])
  135.         ((or (= (size m) 1) (eq? c h)) m)))
  136.  
  137. (define (solve grid)
  138.   (let ([grid (make-grid grid)] [n 'bad]
  139.          [attempt (list)])
  140.     (call-with-current-continuation
  141.       (lambda (out)
  142.         (let search! ([k 0])
  143.           (cond
  144.             [(eq? (right grid) grid)
  145.              (if (eq? n 'bad) (set! n 'good)
  146.                  (out 'many))]
  147.             [else
  148.              (let ([c (optimal-branch grid)])
  149.                (vertical-cover! (header c))
  150.                (do ([r (down c) (down r)])
  151.                      ((eq? r c))
  152.                  (set! attempt (cons r attempt))
  153.                  (horizontal-cover! r)
  154.                  (search! (+ k 1))
  155.                  (let ([x (car attempt)])
  156.                    (set! attempt (cdr attempt))
  157.                    (set! r x)) (set! c (header r))
  158.                  (horizontal-uncover! r))
  159.                (vertical-uncover!
  160.                  (header c)))])) (out n)))))
  161. )) ;; End of library.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement