Skip to content

Instantly share code, notes, and snippets.

@nyuichi
Created May 25, 2011 13:44
Show Gist options
  • Save nyuichi/990995 to your computer and use it in GitHub Desktop.
Save nyuichi/990995 to your computer and use it in GitHub Desktop.
Sisoku@clojure
(use 'clojure.contrib.combinatorics)
; How to use
; (sisoku [7 7 7 9 11 11] 218/100)
; (sisoku [1 1 6 11 12 13] 314/100)
(defn drop-nth [n coll]
(concat (take n coll)
(drop (inc n) coll)))
(defn comb [n m]
(combinations (range n) m))
(def comb (memoize comb))
(defn choose-2 [coll n m]
(let [a (nth coll n)
b (nth coll m)
rest (drop-nth n (drop-nth m coll))]
[a b rest]))
(defn choose-2-in-order [coll]
(for [[a b] (comb (count coll) 2)]
(choose-2 coll a b)))
(defn single? [coll]
(empty? (rest coll)))
(defn insert [v coll]
(let [[head tail] (split-with #(< v %) coll)]
(concat head [v] tail)))
(defmacro forcat [seq-exprs body-expr]
`(apply concat (for ~seq-exprs ~body-expr)))
(defmacro go [op a b]
`(let [r# (~op ~a ~b)
n# (insert r# ~'coll)
s# (sisoku n# ~'answer)]
(if (empty? s#)
s#
(map #(conj % (str '~op) ~a ~b) s#))))
(defn sisoku
"Return a sequence of answers"
[seeds answer]
(if (single? seeds)
(if (= (first seeds) answer)
[seeds]
[])
(forcat [[a b coll] (choose-2-in-order seeds)]
(concat (go + a b)
(go - a b)
(go - b a)
(go * a b)
(when-not (zero? b)
(go / a b))
(when-not (zero? a)
(go / b a))))))
(def sisoku (memoize sisoku))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment