Clojure reduce with argument destructuring

Viewed 92

I am currently working on an assignment to come up with a solution for a simple "compression/ encoding" algorithm. Objective is to compress subsequent identical letters in a string: "AABBBCCCC" --> "2A3B4C"

Although there are several (and possibly more elegant) approaches to this solution, I got stuck trying to derive a single reduce function that counts subsequent appearances of the same letter, building up the output array:

(reduce (fn [[a counter seq] b]
   (if (= a b) [b (inc counter) seq] ([b 0 (conj(conj seq b )counter)] )))
   [ "" 0 [] ] 
   "AABBBCCCC")

However, trouble starts already with my destructuring attempt of the reducer function which should be of type:

fn [[char int []] char] -> [char int []]

I could already figure out there is another solution to the problem using the identity macro. However, I still would like to get the reducer working. Any suggestion and help is much appreciated!

1 Answers

the reduce variant could be something like this:

(defn process [s]
  (->> (reduce (fn [[res counter a] b]
                 (if (= a b)
                   [res (inc counter) b]
                   [(conj res counter a) 1 b]))
               [[] 0 nil]
               s)
       (apply conj)
       (drop 2)
       (apply str)))

user> (process "AABBCCCCC")
;;=> "2A2B5C"

though i would probably go with clojure's sequence functions:

(->> "AABBCCCC"
     (eduction (partition-by identity)
               (mapcat (juxt count first)))
     (apply str))
;;=> "2A2B4C"
Related