inverse of interleave = unravel

325 views
Skip to first unread message

Konrad Kułakowski (kony)

unread,
Dec 2, 2009, 12:10:45 PM12/2/09
to Clojure
Recently I need something which works as "inverse of interleave"

I did something like that:

(defn unravel [expr-list]
(loop [flist () slist () tic-tac 0 olist expr-list]
(let [item (first olist)]
(if (= item nil)
(list flist slist)
(if (= tic-tac 0)
(recur (concat flist (list item)) slist 1 (rest olist))
(recur flist (concat slist (list item)) 0 (rest olist)))))))

Test:

(def dl (interleave (iterate inc 1) ["A" "B" "C" "D" "E"]))
(unravel dl)

And the "classic" question is it possible to do it simple, more in a
"functional manner", without explicit looping?

Wilson MacGyver

unread,
Dec 2, 2009, 12:30:56 PM12/2/09
to clo...@googlegroups.com
the only solution comes to mind is a two pass partition.

ie

(flatten (partition 1 2 dl)) for the first list
and (flatten (partition 1 2 (rest dl))) for the 2nd list.


2009/12/2 Konrad Kułakowski (kony) <kulak...@gmail.com>:
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en



--
Omnem crede diem tibi diluxisse supremum.

ataggart

unread,
Dec 2, 2009, 2:06:07 PM12/2/09
to Clojure


On Dec 2, 9:10 am, Konrad Kułakowski (kony) <kulakow...@gmail.com>
wrote:
How about this?

(defn skip [coll n]
(lazy-seq
(when-let [s (seq coll)]
(cons (first s) (skip (drop n (next s)) n)))))

(defn unravel [coll n]
(for [i (range n)]
(skip (drop i coll) (dec n))))

Christophe Grand

unread,
Dec 2, 2009, 3:01:00 PM12/2/09
to clo...@googlegroups.com
Hi,

2009/12/2 Konrad Kułakowski (kony) <kulak...@gmail.com>
Recently I need something which works as "inverse of interleave"

(defn unravel [s]
  [(take-nth 2 s) (take-nth 2 (rest s))])
 

Christophe

--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.cgrand.net/ (en)

Chouser

unread,
Dec 2, 2009, 3:02:52 PM12/2/09
to clo...@googlegroups.com
On Wed, Dec 2, 2009 at 2:06 PM, ataggart <alex.t...@gmail.com> wrote:
>
>
> On Dec 2, 9:10 am, Konrad Kułakowski (kony) <kulakow...@gmail.com>
> wrote:
>> Recently I need something which works as "inverse of interleave"
>
> How about this?
>
> (defn skip [coll n]
>  (lazy-seq
>    (when-let [s (seq coll)]
>      (cons (first s) (skip (drop n (next s)) n)))))
>
> (defn unravel [coll n]
>  (for [i (range n)]
>    (skip (drop i coll) (dec n))))

Not bad. Your unravel takes an n, which is needed because
interleave accepts any number of collections, not just two. Your
'skip' is a lot like take-nth. Here's what I had:

(defn unravel [n coll]
(map #(take-nth n (drop % coll)) (range n)))

--Chouser

ataggart

unread,
Dec 2, 2009, 3:12:14 PM12/2/09
to Clojure


On Dec 2, 12:02 pm, Chouser <chou...@gmail.com> wrote:
Ah, I forgot about take-nth.
Reply all
Reply to author
Forward
0 new messages