Yet another variation: (defn conjugate [f g & [g-inv]] (comp (or g-inv g) f g))
(defn composite [f f-inv n x] (nth (iterate (if (pos? n) f f-inv) x) (abs n))) (defn rotate-left [xs] (when (seq xs) (concat (rest xs) [(first xs)]))) (def rotate-right (conjugate rotate-left reverse)) (defn rotate [n xs] (composite rotate-left rotate-right n xs)) This is intended to expose certain symmetries. One of the basic ideas in mathematics is that an invertible transformation T acts on elements by application, so that x becomes T(x), and on functions by conjugation, so that f becomes T^(-1) . f . T. Another basic idea is that iterated compositions are like powers: f^n is the n-fold composition of f. This is what iterate tries to capture. This is meaningful for negative values of n when f is invertible. This is what composite tries to capture. If there were more direct support for doubly-infinite sequences (a fun little programming exercise) then composite could return a doubly-infinite sequence (much like iterate returns a singly-infinite sequence), take would work with negative arguments, next would have a counterpart prev, etc. Another fun exercise is to provide more direct support for invertible functions. An invertible function can be represented by a pair of functions. It implements IFn by applying the first element of the pair. Inverting is just a matter of swapping the elements. Food for thought. :) -Per On Wed, Apr 21, 2010 at 10:23 PM, Sean Devlin <francoisdev...@gmail.com> wrote: > Hey everyone, > > I've had to code these guys up a few times: > > (defn rotate > "Take a collection and left rotates it n steps. If n is negative, > the > collection is rotated right. Executes in O(n) time." > [n coll] > (let [c (count coll)] > (take c (drop (mod n c) (cycle coll))))) > > (defn rotate-while > "Rotates a collection left while (pred item) is true. Will return a > unrotated > sequence if (pred item) is never true. Executes in O(n) time." > [pred coll] > (let [head (drop-while pred coll)] > (take (count coll) (concat head coll)))) > > Have other people had this problem? > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en