Skip to content

Instantly share code, notes, and snippets.

@leifp
Last active August 29, 2015 14:01
Show Gist options
  • Save leifp/b4af5f4cd7289c38b55a to your computer and use it in GitHub Desktop.
Save leifp/b4af5f4cd7289c38b55a to your computer and use it in GitHub Desktop.
core.logic solution to the Mensa Puzzle Calendar puzzle for April 8, 2014
(require '[clojure.core.logic :refer :all])
(require '[clojure.core.logic.fd :as fd])
(defn more-than-one-apart [x y]
(conde
[(fd/eq (> (- x y) 1))]
[(fd/eq (> (- y x) 1))]))
(defn billiards []
(let [dom (fd/interval 1 10)
vars (repeatedly 10 lvar)
slice (fn [coll b e] (take (- e b) (drop b coll)))
[r4 r3 r2 r1] (for [i [[0 4] [4 7] [7 9] [9 10]]]
(apply slice vars i))
[x11] r1
[x21 x22] r2
[x31 x32 x33] r3
[x41 x42 x43 x44] r4]
(run 1 [q]
(== q vars)
(everyg #(fd/in % (fd/interval 1 10)) vars)
(fd/distinct vars)
(fresh [s2 s3]
(fd/in s2 s3 (fd/interval 1 30))
;; A. In the 3-ball row, numbers are in ascending order from left
;; to right with each successive ball 3 higher than the one
;; before it
(fd/- x33 x32 3)
(fd/- x32 x31 3)
(fd/eq
;; B: The sum of the 3-ball row = the sum of the 2-ball row
(= (+ x21 x22) s2)
(= (+ x31 x32 x33) s3)
(= s2 s3)
;; C: The sum of the 4 balls on the left edge = the sum of the
;; balls on the right edge = 20
(= (+ x11 x21 x31 x41) 20)
(= (+ x11 x22 x33 x44) 20)
;; D: The total sum of the balls in the 1-ball and 2-ball
;; rows = 20
(= (+ s2 x11) 20))
;; E: Adjacent numbers in the 4-ball row are more than 1 apart
(more-than-one-apart x41 x42)
(more-than-one-apart x43 x44)
(more-than-one-apart x42 x43)))))
;; user=> (time (doall (billiards)))
;; "Elapsed time: 227.923952 msecs"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment