Saturday, February 08, 2014

99 Clojure Problems – 19: Rotate a List N Places to the Left

Example:

(deftest p19-rotate
  (is (= '(d e f g h i j k a b c) (rotate 3 '(a b c d e f g h i j k))))
  (is (= '(j k a b c d e f g h i) (rotate -2 '(a b c d e f g h i j k)))))

Solution:

The examples illustrate that the sign of the first parameter determines the direction of rotation. A positive integer is meant to indicate that we want to rotate N places to left counting from the beginning of the input sequence. A negative integer means start counting from the end of the input sequence.

My solution calculates the split point accordingly and reuses the solution to problem 17 to split the input sequence. All of this happens in an initial let binding, thus we can use destructuring to bind the result of the split operation to two symbols. I called the second sublist "newhead" and the first sublist "newtail". We can then simple concatenate the two parts in the order indicated by the symbol names to create the rotated list.

Read more about this series.

2 comments:

Anonymous said...

Thanks for the great blog. I have been looking for something like this.

Your function can be improved by using a modulus:

(defn rotate [n xs]
"P19 (**) Rotate a list N places to the left."
(let [at (mod n (count xs))
[newtail newhead] (split at xs)]
(concat newhead newtail)))

Peter Brachwitz said...

Yes you are absolutely right. Well spotted!