octopusgrabbus
octopusgrabbus

Reputation: 10685

How to apply a function to a sequence multiple times

I am working on some Lisp exercises using Clojure. I am trying to work these exercises without taking advantage of vectors and some Clojure functions.

This function

(defn rev-seq
    [s1]
    (concat (pop s1) (list (peek s1))))

puts the first element of a list at the end. I want to call this function as many times as it takes to reverse the list (without calling Clojure's reverse function).

I am not sure what to use in its place. I have experimented with map, apply, and repeat with no success. I would rather have a way to think differently about this than a straight answer, but I am not asking for a discussion.

Upvotes: 2

Views: 1308

Answers (2)

tnoda
tnoda

Reputation: 1524

Recursion is powerful! I translated the solution into Clojure.

(defn- inverte-aux
  [lista resto]
  (if lista
    (recur (next lista) (cons (first lista) resto))
    resto))

(defn inverte
  [lista]
  (inverte-aux lista nil))

user> (inverte [4 3 2 1 3])
(3 1 2 3 4)

Upvotes: 1

mikera
mikera

Reputation: 106351

Firstly, I think you'll need to convert rev-seq to use first/rest rather than peek/pop if you want to work on general sequences - at leas in Clojure 1.4 peek/pop seems to require a PersistentStack:

(defn rev-seq
  [s1]
  (concat (rest s1) (list (first s1))))

Then you should probably note that applying this function repeatedly will "cycle" a list rather than reversing it. You can see that if you look at the result of a small number of applications using iterate:

(def s '(1 2 3 4 5 6 7 8 9))

(nth (iterate rev-seq s) 3)
=> (4 5 6 7 8 9 1 2 3)

An option that would work is to reverse with a recursive function:

(defn reverse-seq [s]
  (concat (reverse (next s)) (list (first s))))

(reverse-seq s)
=> (9 8 7 6 5 4 3 2 1)

Or alternatively you can do a reverse using the technique in clojure.core:

(defn reverse-seq [s]
  (reduce conj () s))

(reverse-seq s)
=> (9 8 7 6 5 4 3 2 1)

Hope this gives you some ideas!

Upvotes: 4

Related Questions