Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic string rotation in Clojure

How to idiomatically rotate a string in Clojure for the Burrows-Wheeler transform?

I came up with this, which uses (cycle "string"), but feels a bit imperative:

(let [s (str "^" "banana" "|")
      l (count s)
      c (cycle s)
      m (map #(take l (drop % c)) (range l))]
  (apply map str m))
=> ("^banana|" "banana|^" "anana|^b" "nana|^ba" "ana|^ban" "na|^bana" "a|^banan" "|^banana")

I'm not sure if this qualifies as code golf. Is there a cleaner way to do this?

like image 294
Petrus Theron Avatar asked Jan 19 '26 16:01

Petrus Theron


1 Answers

I would do:

(defn bwrot [s]
  (let [s (str "^" s "|")]
    (for [i (range (count s))]
      (str (subs s i) (subs s 0 i)))))

or:

(defn bwrot [s]
  (let [n (+ 2 (count s))
        s (str "^" s "|^" s "|")]
    (for [i (range n)]
      (subs s i (+ i n)))))

The second one should allocate less (one string instead of three per iteration).

like image 160
cgrand Avatar answered Jan 21 '26 09:01

cgrand



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!