2

I have an infinite lazy sequence that produce a "preamble" and a "pattern repetition", a simple example of this kind of sequence could be implemented in Clojure with:

(def infinite-lazy-sequence
  (lazy-cat [4] (cycle [1 2 3])))

=> (take 20 infinite-lazy-sequence)
(4 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1)

I would like to get a set of the elements forming this infinite-lazy-sequence, here is a way to implement it using loop:

(loop
  [[head & tail] infinite-lazy-sequence
   result #{}]
  (if (contains? result head)
    result
    (recur tail (conj result head))))

=> #{1 2 3 4}

Here is the question: is it possible to achieve the same result using reduce? And using take-while?

Edit:

Benchmark results using clojure-1.5.1 and perforate-0.2.4

proposed loop-recur implementation:

Case:  :loop-recur
Evaluation count : 60 in 60 samples of 1 calls.
             Execution time mean : 1.054975 sec
    Execution time std-deviation : 26.316442 ms
   Execution time lower quantile : 1.026187 sec ( 2.5%)
   Execution time upper quantile : 1.125854 sec (97.5%)

@sw1nn reduce-reduced implementation:

Case:  :reduce-reduced
Evaluation count : 120 in 60 samples of 2 calls.
             Execution time mean : 875.091831 ms
    Execution time std-deviation : 19.745142 ms
   Execution time lower quantile : 850.871606 ms ( 2.5%)
   Execution time upper quantile : 921.947759 ms (97.5%)
2
  • So no element in your infinite sequence may occur twice before the repeated pattern starts repeating, is that correct? Commented Mar 25, 2013 at 21:59
  • Yes, it is correct. Unfortunately I don't know how long the preamble could be... Good point. Commented Mar 25, 2013 at 22:01

1 Answer 1

4

Clojure 1.5 added reduced to allow shortcircuiting reduces...

 (reduce (fn [a v] (if-not (a v) (conj a v) (reduced a))) 
         #{} 
         infinite-lazy-sequence)
 => #{1 2 3 4}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks @sw1nn, I have just benchmarked it with my target infinite-lazy-sequence and your reduce-reduced version seems also faster with Clojure 1.5.1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.