Skip to content

Instantly share code, notes, and snippets.

@noprompt
Created September 21, 2017 17:19
Show Gist options
  • Save noprompt/3c485ec493bd7047f364a012ec6b39dd to your computer and use it in GitHub Desktop.
Save noprompt/3c485ec493bd7047f364a012ec6b39dd to your computer and use it in GitHub Desktop.
Permutations in Clojure (based on Heap's algorithm)
(defn swap
"Swap the elements at positions `i` and `j` in `v`."
{:private true}
[v i j]
(-> v
(assoc i (get v j))
(assoc j (get v i))))
;; SEE: https://en.wikipedia.org/wiki/Heap%27s_algorithm
(defn permutations [coll]
(let [v (vec coll)
n (count v)]
(loop [n n
a [v]]
(if (zero? n)
a
(let [n* (dec n)
a* (mapcat
(fn step [v]
(map
(fn [i]
(swap v i n*))
(range n)))
a)]
(recur n* a*))))))
@noprompt
Copy link
Author

noprompt commented Sep 21, 2017

(permutations [:A :B :C :D])
;; =>
([:B :C :D :A]
 [:C :B :D :A]
 [:C :D :B :A]
 [:D :C :B :A]
 [:B :D :C :A]
 [:D :B :C :A]
 [:D :C :A :B]
 [:C :D :A :B]
 [:C :A :D :B]
 [:A :C :D :B]
 [:D :A :C :B]
 [:A :D :C :B]
 [:B :D :A :C]
 [:D :B :A :C]
 [:D :A :B :C]
 [:A :D :B :C]
 [:B :A :D :C]
 [:A :B :D :C]
 [:B :C :A :D]
 [:C :B :A :D]
 [:C :A :B :D]
 [:A :C :B :D]
 [:B :A :C :D]
 [:A :B :C :D])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment