36 lines
948 B
Clojure
36 lines
948 B
Clojure
(defn- iter-perm [v]
|
|
(let [len (count v),
|
|
j (loop [i (- len 2)]
|
|
(cond (= i -1) nil
|
|
(< (v i) (v (inc i))) i
|
|
:else (recur (dec i))))]
|
|
(when j
|
|
(let [vj (v j),
|
|
l (loop [i (dec len)]
|
|
(if (< vj (v i)) i (recur (dec i))))]
|
|
(loop [v (assoc v j (v l) l vj), k (inc j), l (dec len)]
|
|
(if (< k l)
|
|
(recur (assoc v k (v l) l (v k)) (inc k) (dec l))
|
|
v))))))
|
|
|
|
|
|
(defn- vec-lex-permutations [v]
|
|
(when v (cons v (lazy-seq (vec-lex-permutations (iter-perm v))))))
|
|
|
|
(defn lex-permutations
|
|
"Fast lexicographic permutation generator for a sequence of numbers"
|
|
[c]
|
|
(lazy-seq
|
|
(let [vec-sorted (vec (sort c))]
|
|
(if (zero? (count vec-sorted))
|
|
(list [])
|
|
(vec-lex-permutations vec-sorted)))))
|
|
|
|
(defn permutations
|
|
"All the permutations of items, lexicographic by index"
|
|
[items]
|
|
(let [v (vec items)]
|
|
(map #(map v %) (lex-permutations (range (count v))))))
|
|
|
|
(println (permutations [1 2 3]))
|