On Fri, Feb 24, 2012 at 11:30 AM, JuanManuel Gimeno Illa
<jmgim...@gmail.com> wrote:
> Maybe this version is clearer:
>
> (defn split-at-subsequence [mark input]
>     (when-let [sequence (seq input)]
>         (let [len       (count mark)
>               pieces   (partition-all len 1 sequence)
>               [fst rst]  (split-with #(not= mark %) pieces)
>               head      (map first fst)
>               rst-input (map first (drop len rst))
>               tail         (lazy-seq (split-at-subsequence mark rst-input))]
>             (if (empty? head)
>                 tail
>                 (list* head tail)))))
>
> I think it would be better to create the lazy-seq over a function that uses
> the pieces in order to not to explode input with partition-all and
> de-explode it with map-first before the recursive call.

That hangs on the case

(first (second (split-at-subsequence [1 2] (range))))

again. I don't know why; from what I can see, it shouldn't, since
everything seems sufficiently lazy.

Maybe could also use some optimization:

(defn split-at-subsequence [mark input]
  (when-let [sequence (seq input)]
    (let [len      (count mark)
          pieces   (partition-all len 1 sequence)
          step (fn step [rst-input]
                 (when rst-input
                   (lazy-seq
                     (let [[fst rst] (split-with #(not= mark %) rst-input)]
                     (cons fst (step (nthnext rst len)))))))]
      (map #(map first %) (remove nil? (map seq (step pieces)))))))

This avoids computing len and pieces and (map first ...) over and
over, and uses nthnext instead of drop to save some calls to seq. The
split-with could be replaced by a loop to save traversing part of the
sequence twice, but then it would definitely be impossible to fix the
hang with (first (second (split-at-subsequence [1 2] (range)))).

It's probably possible to do quite a bit better, though, perhaps by
using Boyer-Moore, though I'm not sure how easily Boyer-Moore can be
made lazy, especially lazy enough to avoid than hang.

-- 
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