Skip to content

Instantly share code, notes, and snippets.

@gallettilance
Created November 16, 2017 02:10
Show Gist options
  • Save gallettilance/24a6e808ed6b544f4a548b9a347b6bd1 to your computer and use it in GitHub Desktop.
Save gallettilance/24a6e808ed6b544f4a548b9a347b6bd1 to your computer and use it in GitHub Desktop.
Lazy get next permutation
(defn list_reverse [xs]
(letfn [(helper [xs res] (if (empty? xs) res (helper (rest xs) (conj res (first xs)))))]
(helper xs nil)
))
(defn list_length [xs]
(letfn [(helper [xs res] (if (empty? xs) res (helper (rest xs) (+ res 1))))]
(helper xs 0)
))
(defn swap [xs i j]
(concat
(concat
(concat
(concat (take (- i 1) xs) (take 1 (drop (- j 1) xs)))
(take (- (- j i) 1) (drop i xs)))
(take 1 (drop (- i 1) xs)))
(drop j xs))
)
(defn permutate [xs p1 p2]
(if (> (nth xs (- p1 1)) (nth xs p2)) (permutate xs p1 (- p2 1))
(let [xss (swap xs p1 (+ p2 1))] (concat (take p1 xss) (list_reverse (drop p1 xss))))
))
(defn findPivot [xs]
(letfn [(helper [xs i] (if (= i 0) i (if (> (nth xs i) (nth xs (- i 1))) i (helper xs (- i 1)))))]
(helper xs (- (list_length xs) 1)))
)
(defn nextPerm [xs] (let [pivot (findPivot xs)]
(lazy-seq (cons (permutate xs pivot (- (list_length xs) 1))
(nextPerm (permutate xs pivot (- (list_length xs) 1)))))))
(def Perms3 (take 5039 (nextPerm '(1 2 3 4 5 6 7))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment