A working implementation of elimination/trial and error solver
This commit is contained in:
parent
5a74507c79
commit
3c2298127c
1 changed files with 80 additions and 17 deletions
|
@ -29,9 +29,7 @@
|
||||||
col-map (into {} (for [ps (partition 3 cols) e ps] [e ps]))]
|
col-map (into {} (for [ps (partition 3 cols) e ps] [e ps]))]
|
||||||
(for [row (row-map r) col (col-map c)] (str row col))))
|
(for [row (row-map r) col (col-map c)] (str row col))))
|
||||||
|
|
||||||
(defn units [s] (vector (row-keys s) (col-keys s) (box-keys s)))
|
(defn peers [s] (disj (into #{} (concat (row-keys s) (col-keys s) (box-keys s))) s))
|
||||||
|
|
||||||
(defn peers [s] (disj (into #{} (apply concat (units s))) s))
|
|
||||||
|
|
||||||
(declare assign)
|
(declare assign)
|
||||||
(declare eliminate)
|
(declare eliminate)
|
||||||
|
@ -58,24 +56,27 @@
|
||||||
(defn solved? [grid]
|
(defn solved? [grid]
|
||||||
(every? #(= 1 (count %)) (vals grid)))
|
(every? #(= 1 (count %)) (vals grid)))
|
||||||
|
|
||||||
|
(defn try-assign [grid cell value]
|
||||||
|
(ekit/with-handler
|
||||||
|
(assign grid cell value)
|
||||||
|
(ekit/handle *inconsistent-grid* [] nil)))
|
||||||
|
|
||||||
|
(defn try-eliminate [grid cell value]
|
||||||
|
(ekit/with-handler
|
||||||
|
(eliminate grid cell value)
|
||||||
|
(ekit/handle *inconsistent-grid* [] nil)))
|
||||||
|
|
||||||
(defn solve [grid]
|
(defn solve [grid]
|
||||||
(if (solved? grid)
|
(when grid
|
||||||
grid
|
(if (solved? grid)
|
||||||
(let [cell (first (filter #(> (count (grid %)) 1) (keys grid)))
|
grid
|
||||||
candidates (grid cell)
|
(let [cell (first (filter #(> (count (grid %)) 1) (keys grid)))
|
||||||
candidate (first candidates)]
|
value (first (grid cell))]
|
||||||
(ekit/with-handler
|
(or (solve (try-assign grid cell value)) (solve (try-eliminate grid cell value)))))))
|
||||||
(do
|
|
||||||
(println (str "Trying " cell "=" candidate))
|
|
||||||
(recur (assign grid cell candidate)))
|
|
||||||
(ekit/handle *inconsistent-grid* []
|
|
||||||
(if (next candidates)
|
|
||||||
(do (println (str "Trying next candidate for " cell))
|
|
||||||
(recur (eliminate grid cell candidate)))
|
|
||||||
(ekit/do-not-handle)))))))
|
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
|
|
||||||
|
;; This is a trivial puzzle: it is solved by the initial assignment
|
||||||
(def g1 (parse-grid
|
(def g1 (parse-grid
|
||||||
"003020600
|
"003020600
|
||||||
900305001
|
900305001
|
||||||
|
@ -87,5 +88,67 @@
|
||||||
800203009
|
800203009
|
||||||
005010300"))
|
005010300"))
|
||||||
|
|
||||||
|
(solved? g1)
|
||||||
|
;;=> true
|
||||||
|
|
||||||
(def g2 (parse-grid "400000805030000000000700000020000060000080400000010000000603070500200000104000000"))
|
(def g2 (parse-grid "400000805030000000000700000020000060000080400000010000000603070500200000104000000"))
|
||||||
|
|
||||||
|
(print-grid g2)
|
||||||
|
;; ...4..... 1....67.9 12...67.9 | 1.3.....9 .23..6..9 12...6..9 | .......8. 123.....9 ....5....
|
||||||
|
;; .2...6789 ..3...... 12..56789 | 1..45..89 .2.456..9 12.456.89 | 12...67.9 12.4....9 12.4.67.9
|
||||||
|
;; .2...6.89 1...56.89 12..56.89 | ......7.. .23456..9 12.456.89 | 123..6..9 1234....9 1234.6..9
|
||||||
|
;; ------------------------------+-------------------------------+------------------------------
|
||||||
|
;; ..3...789 .2....... 1.3.5.789 | ..345...9 ..345.7.9 ...45.7.9 | 1.3.5.7.9 .....6... 1.3...789
|
||||||
|
;; ..3..67.9 1...567.9 1.3.567.9 | ..3.5...9 .......8. .2..567.9 | ...4..... 123.5...9 123...7.9
|
||||||
|
;; ..3..6789 ...456789 ..3.56789 | ..345...9 1........ .2.4567.9 | .23.5.7.9 .23.5..89 .23...789
|
||||||
|
;; ------------------------------+-------------------------------+------------------------------
|
||||||
|
;; .2.....89 .......89 .2.....89 | .....6... ...45...9 ..3...... | 12..5...9 ......7.. 12.4...89
|
||||||
|
;; ....5.... .....6789 ..3..6789 | .2....... ...4..7.9 1..4..789 | 1.3..6..9 1.34...89 1.34.6.89
|
||||||
|
;; 1........ .....6789 ...4..... | ....5..89 ....5.7.9 ....5.789 | .23.56..9 .23.5..89 .23..6.89
|
||||||
|
|
||||||
|
;; More tricky...
|
||||||
|
(solved? g2)
|
||||||
|
;;=> false
|
||||||
|
|
||||||
|
(def s (solve g2))
|
||||||
|
(solved? s)
|
||||||
|
;;=> true
|
||||||
|
|
||||||
|
(print-grid s)
|
||||||
|
;; ...4..... 1........ ......7.. | ..3...... .....6... ........9 | .......8. .2....... ....5....
|
||||||
|
;; .....6... ..3...... .2....... | 1........ ....5.... .......8. | ........9 ...4..... ......7..
|
||||||
|
;; ........9 ....5.... .......8. | ......7.. .2....... ...4..... | ..3...... 1........ .....6...
|
||||||
|
;; ------------------------------+-------------------------------+------------------------------
|
||||||
|
;; .......8. .2....... ....5.... | ...4..... ..3...... ......7.. | 1........ .....6... ........9
|
||||||
|
;; ......7.. ........9 1........ | ....5.... .......8. .....6... | ...4..... ..3...... .2.......
|
||||||
|
;; ..3...... ...4..... .....6... | ........9 1........ .2....... | ......7.. ....5.... .......8.
|
||||||
|
;; ------------------------------+-------------------------------+------------------------------
|
||||||
|
;; .2....... .......8. ........9 | .....6... ...4..... ..3...... | ....5.... ......7.. 1........
|
||||||
|
;; ....5.... ......7.. ..3...... | .2....... ........9 1........ | .....6... .......8. ...4.....
|
||||||
|
;; 1........ .....6... ...4..... | .......8. ......7.. ....5.... | .2....... ........9 ..3......
|
||||||
|
|
||||||
|
(def g3 (parse-grid
|
||||||
|
"008601000
|
||||||
|
600000003
|
||||||
|
000048506
|
||||||
|
040000600
|
||||||
|
780020091
|
||||||
|
001000030
|
||||||
|
109870000
|
||||||
|
200000007
|
||||||
|
000209100"))
|
||||||
|
|
||||||
|
(print-grid (solve g3))
|
||||||
|
;; ...4..... ..3...... .......8. | .....6... ....5.... 1........ | .2....... ......7.. ........9
|
||||||
|
;; .....6... 1........ ....5.... | ......7.. ........9 .2....... | .......8. ...4..... ..3......
|
||||||
|
;; ........9 .2....... ......7.. | ..3...... ...4..... .......8. | ....5.... 1........ .....6...
|
||||||
|
;; ------------------------------+-------------------------------+------------------------------
|
||||||
|
;; ..3...... ...4..... .2....... | ........9 1........ ......7.. | .....6... ....5.... .......8.
|
||||||
|
;; ......7.. .......8. .....6... | ....5.... .2....... ..3...... | ...4..... ........9 1........
|
||||||
|
;; ....5.... ........9 1........ | ...4..... .......8. .....6... | ......7.. ..3...... .2.......
|
||||||
|
;; ------------------------------+-------------------------------+------------------------------
|
||||||
|
;; 1........ .....6... ........9 | .......8. ......7.. ....5.... | ..3...... .2....... ...4.....
|
||||||
|
;; .2....... ....5.... ..3...... | 1........ .....6... ...4..... | ........9 .......8. ......7..
|
||||||
|
;; .......8. ......7.. ...4..... | .2....... ..3...... ........9 | 1........ .....6... ....5....
|
||||||
|
|
||||||
)
|
)
|
Loading…
Reference in a new issue