Skip to content

Instantly share code, notes, and snippets.

@jooyunghan
Created September 18, 2015 16:46
Show Gist options
  • Save jooyunghan/cf36dc3641e272734b1a to your computer and use it in GitHub Desktop.
Save jooyunghan/cf36dc3641e272734b1a to your computer and use it in GitHub Desktop.
fox/goose/corn puzzle from Living Clojure Kata
(ns fox-goose-bag-of-corn.puzzle)
(def start-pos [[[:fox :goose :corn :you] [:boat] []]])
(defn end? [state]
(= state [#{} #{:boat} #{:you :goose :fox :corn}]))
(defn next-moves' [[left boat right]]
(cond (left :you)
(into [[(disj left :you) (conj boat :you) right]] ;; move alone
(map (fn [animal] [(disj left :you animal) (conj boat :you animal) right]) (disj left :you)))
(right :you)
(into [[left (conj boat :you) (disj right :you)]] ;; move alone
(map (fn [animal] [left (conj boat :you animal) (disj right :you animal)]) (disj right :you)))
:else (let [animal (first (disj boat :boat :you))]
[[(conj left :you) (disj boat :you) right]
[left (disj boat :you) (conj right :you)]
[(conj left :you animal) #{:boat} right]
[left #{:boat} (conj right :you animal)]])))
(defn eat? [[left boat right]]
(or (and (every? left [:goose :fox]) (not (left :you)))
(and (every? left [:goose :corn]) (not (left :you)))
(and (every? right [:goose :fox]) (not (right :you)))
(and (every? right [:goose :corn]) (not (right :you)))))
(defn next-moves [trace seen]
(map #(conj trace %) (remove eat? (remove seen (next-moves' (last trace))))))
(defn search [trace seen to-visit]
(let [cur (last trace)]
(cond (end? cur) trace
(seen cur) (recur (first to-visit) seen (rest to-visit))
:else (recur trace (conj seen cur) (concat to-visit (next-moves trace seen))))))
(defn river-crossing-plan []
(map (partial mapv vec)(search (mapv (partial map set) start-pos) #{} '())))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment