Created
April 17, 2012 02:24
-
-
Save budu/2402996 to your computer and use it in GitHub Desktop.
Logic puzzle: XKCD #287 solution in Clojure core.logic
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
(use 'clojure.core.logic) | |
(def rvar? (comp not lvar?)) | |
(defmacro arithm [r x y op po] | |
`(fn [a#] | |
(let [r# (walk a# ~r) | |
x# (walk a# ~x) | |
y# (walk a# ~y)] | |
(cond | |
(and (lvar? r#) (rvar? x#) (rvar? y#)) | |
(or (unify a# ~r (~op x# y#)) nil) | |
(and (rvar? r#) (lvar? x#) (rvar? y#)) | |
(or (unify a# ~x (~po r# y#)) nil) | |
(and (rvar? r#) (rvar? x#) (lvar? y#)) | |
(or (unify a# ~y (~po r# x#)) nil) | |
(and (rvar? r#) (rvar? x#) (rvar? y#) | |
(clojure.core/= r# (~op x# y#))) a# | |
:else nil)))) | |
(defmacro plus [r x y] | |
`(arithm ~r ~x ~y + -)) | |
(defmacro mul [r x y] | |
`(arithm ~r ~x ~y * /)) | |
(defne mulseqo [xs ys zs] | |
([[] [] []]) | |
([[x . xt] [y . yt] _] | |
(fresh [z zt] | |
(conso z zt zs) | |
(mul z x y) | |
(mulseqo xt yt zt)))) | |
(defne reduceaddo [r coll] | |
([0 []]) | |
([_ [x . tail]] | |
(fresh [z] | |
(plus r x z) | |
(reduceaddo z tail)))) | |
(defn xkcd287 [] | |
(run* [q] | |
(fresh [total prices counts amounts mf ff ss hw ms sp] | |
(== total 1505) | |
(== prices [215 275 335 355 420 580]) | |
(== counts [mf ff ss hw ms sp]) | |
(ino [mf ff ss hw ms sp] (range 8)) | |
(mulseqo prices counts amounts) | |
(reduceaddo total amounts) | |
(== q [prices counts])))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment