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

Reply via email to