Skip to content

Instantly share code, notes, and snippets.

@noprompt
Created March 19, 2019 02:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noprompt/6a4624a81908baf60263dcd4efeda4d8 to your computer and use it in GitHub Desktop.
Save noprompt/6a4624a81908baf60263dcd4efeda4d8 to your computer and use it in GitHub Desktop.
(defn swap
"Swap the elements at positions `i` and `j` in `v`."
{:private true}
[v i j]
(-> v
(assoc i (nth v j))
(assoc j (nth v i))))
;; SEE: https://en.wikipedia.org/wiki/Heap%27s_algorithm
(defn permutations
"Return a sequence of all the ways to arrange coll."
[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*))))))
(defn k-combinations
"All the ways to choose k items from coll."
[coll k]
(if (= k 1)
(sequence (map vector) coll)
(let [coll (vec coll)
n (count coll)]
(sequence
(comp
(reduce comp
(repeat (dec k)
(mapcat
(fn [v]
(let [i (peek v)]
(map conj (repeat v) (range i)))))))
(mapcat permutations)
(map
(fn [ptrs]
(mapv nth (repeat coll) ptrs))))
(map vector (range n))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment