Created
July 11, 2012 06:43
-
-
Save martintrojer/3088470 to your computer and use it in GitHub Desktop.
queens blog, part 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defne nqueenso [l n] | |
([() _]) ;; queen list empty, s# | |
([[[x y] . t] _] ;; match/destruct head.tail, ignore n | |
(nqueenso t n) | |
(membero x (range n)) | |
(safeo [x y] t))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defmacro queens-run | |
"Search for all N queens solutions" | |
[n] | |
(let [xnames (->> (range n) (map (fn [_] (gensym "x"))) (into [])) | |
gen-safeos (fn [] | |
(->> (range (dec n)) | |
(map (fn [x] [x (range (inc x) n)])) | |
(map (fn [[s ts]] | |
(map (fn [t] `(safeo [~(nth xnames s) ~s] | |
[~(nth xnames t) ~t])) ts))) | |
(apply concat))) | |
] | |
`(run* [r#] | |
(fresh [~@(map #(nth xnames %) (range n))] | |
~@(map (fn [x] (list 'membero (xnames x) (into [] (range n)))) (range n)) | |
~@(gen-safeos) | |
(== r# [~@(map (fn [x] [(nth xnames x) x]) | |
(range n))]))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defne safeo | |
"Is the queen q safe from all queens in list others" | |
[q others] | |
([_ ()]) ;; others empty, s# | |
([[x1 y1] [[x2 y2] . t]] ;; destruct q and head.tail of others | |
(!= x1 x2) | |
(!= y1 y2) | |
(project [x1 x2 y1 y2] | |
(!= (- x2 x1) (- y2 y1)) | |
(!= (- x1 y2) (- x2 y1))) | |
(safeo [x1 y1] t))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn safeo [[x1 y1] [x2 y2]] | |
(all | |
(!= x1 x2) | |
(!= y1 y2) | |
(project [x1 x2 y1 y2] | |
(!= (- x2 x1) (- y2 y1)) | |
(!= (- x1 y2) (- x2 y1))))) |
Indeed! I'm writing the blog post right now, these gists are used to build up to the grand finale! :)
(declare noattacko)
(defne nqueenso [l n]
([() _])
([[[x y] . others] _]
(nqueenso others n)
(membero y (range 1 (inc n)))
(noattacko [x y] others)))
(defne noattacko [q others]
([_ ()])
([[x y] [[x1 y1] . r]]
(!= y y1)
(project [y y1 x x1]
(!= (- y1 y) (- x1 x))
(!= (- y1 y) (- x x1)))
(noattacko [x y] r)))
(defn solve-nqueens [n]
(run* [q]
(== q (map vector (range 1 (inc n)) (repeatedly lvar)))
(nqueenso q n)))
Oh haha, cool pasted before I saw your reply :)
Thanks for all the help btw, you're a star. I've gotta bring you a box of chocolates if I manage to get to the next conj :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You don't need a macro to generalize nqueens to N. You can create logic vars on the fly.