Created
March 8, 2011 19:47
-
-
Save fogus/860878 to your computer and use it in GitHub Desktop.
Run-length encoding a seq
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn mundane-pack | |
"Mundane recursive way to pack a sequence" | |
[[f & r :as S]] | |
(if (seq S) | |
(let [[packed tail] (split-with {f true} S)] | |
(if (seq tail) | |
(cons packed (mundane-pack tail)) | |
[packed])) | |
[nil])) | |
(defn pack | |
"Tail-recursive way to pack a sequence" | |
[coll] | |
(letfn [(pack* [[f & r :as S] acc] | |
(when (seq S) | |
(let [[packed tail] (split-with {f true} S)] | |
(if (seq tail) | |
(recur tail (conj acc packed)) | |
(conj acc packed)))))] | |
(pack* coll []))) | |
(defn rle | |
"Run-length encode a sequence" | |
[coll] | |
(map #(vector (count %) (first %)) | |
(pack coll))) | |
(def S '[a a a a b c c a a d e e e e]) | |
(pack S) | |
;=> [(a a a a) (b) (c c) (a a) (d) (e e e e)] | |
(rle S) | |
;=> ([4 a] [1 b] [2 c] [2 a] [1 d] [4 e]) | |
Thanks for the tips. I added the {f true}
but am holding off on the *-let
for now as the above reads a little clearer to me.
de gustibus non est disputandum
I'm too enamoured with *-let...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Beware of the #{f}, {f true} is more robust. And you are not an if-let and when-let lover isn't it?