Clojure Kata

241 views
Skip to first unread message

Sean Devlin

unread,
Jan 24, 2010, 3:31:21 PM1/24/10
to Clojure
I recently found a scheme problem that I think would be a good
exercise for a new Clojure developer. I've written about it here:

http://fulldisclojure.blogspot.com/2010/01/code-kata-data-sifter.html

Have fun.
Sean

CuppoJava

unread,
Jan 24, 2010, 3:58:57 PM1/24/10
to Clojure
It's an elegant puzzle. Thanks Sean!

Here's my take:
(defn sift [pred? s]
(lazy-seq
(if (seq s)
(let [key (first s)
[vals remaining] (split-with #(not (pred? %)) (rest s))]
(cons [key vals] (sift pred? remaining))))))

Running:
(sift string? ["a" 2 "b" 3 4 "c" "d" 4])

Returns:
(["a" (2)] ["b" (3 4)] ["c" ()] ["d" (4)])

I'm interested in what you came up with. =)
-Patrick

Travis

unread,
Jan 24, 2010, 7:06:47 PM1/24/10
to Clojure
Occasionally things like this remind me of the similarities between
parsing character sequences and dealing with unpredictably ordered
collections. For character sequences, the regular expression mechanism
has been invented. I wonder if any one else has ever wished for the
ability to write a regular expression for a seq of typed objects.

(defn sift [character-sequence]
(lazy-seq (if-let [
[_ firstsection remainder] (re-find #"(\w\d*)(.*)" (apply str
character-sequence))
]
(cons (list (first firstsection) (rest firstsection))
(sift remainder)))))

The analog to a character class would be a function taking an object
and returning true or false for whether it matches. Something like
this might be an equivalent regular expression for the given problem.

(defn is-delimiter [listitem]
(re-matches #"\w" (str listitem)))
(defn is-data [listitem]
(re-matches #"\d" (str listitem)))
(defn wildcard [listitem] true)
(def regular-expression (list \( is-delimiter is-data \* \) \
( wildcard \) ))

Make sense?

CuppoJava

unread,
Jan 24, 2010, 9:23:20 PM1/24/10
to Clojure
That's very thoughtful Travis. I was also considering generalizing
regular expressions to apply to arbitrary ordered collections for this
question. That is the most elegant abstraction for this problem. I
suppose there just isn't enough real-world use for a regex on
collections to justify the effort in creating such a package. I
personally can't come up with a use-case.

-Patrick

Christophe Grand

unread,
Jan 25, 2010, 5:21:06 AM1/25/10
to clo...@googlegroups.com
Hi Patrick,

On Sun, Jan 24, 2010 at 9:58 PM, CuppoJava <patrick...@hotmail.com> wrote:
> It's an elegant puzzle. Thanks Sean!
>
> Here's my take:
> (defn sift [pred? s]
>  (lazy-seq
>    (if (seq s)
>      (let [key (first s)
>            [vals remaining] (split-with #(not (pred? %)) (rest s))]
>        (cons [key vals] (sift pred? remaining))))))
>

> I'm interested in what you came up with. =)
>  -Patrick

Mine looks very much like yours:
(defn sift [pred coll]
(lazy-seq
(when-let [[x & xs] (seq (drop-while (complement pred) coll))]
(cons [x (take-while (complement pred) xs)] (sift pred xs)))))

except that I discard the first items when they don't match pred,
while you assume that the first item always match pred.
I prefer to use when instead of if when there's no "else" expression.

I also have a non-lazy solution:
(defn sift [pred coll]
(letfn [(alter-top [v f & args] (conj (pop v) (apply f (peek v) args)))]
(reduce #(if (pred %2)
(conj %1 [%2 []])
(alter-top %1 alter-top conj %2)) [] coll)))

Christophe

Edmund

unread,
Jan 25, 2010, 5:35:54 AM1/25/10
to Clojure
Here a different version, without the sequence abstraction. I realise
its idiomatically obsolete, but thought you guys might enjoy it.

(defn sift
"Sift. Old Skool."
[key-pred in-s]
(reduce
(fn [coll elem]
(if (key-pred elem)
(conj coll [(str elem) []])
(conj
(pop coll)
[(first (last coll))
(conj (last (last coll)) (str elem))])))
[]
in-s))

On Jan 25, 10:21 am, Christophe Grand <christo...@cgrand.net> wrote:
> Hi Patrick,
>

Meikel Brandmeyer

unread,
Jan 25, 2010, 6:22:55 AM1/25/10
to Clojure
Golf! Yeah!

Here the low-level version:

(defn sift
[pred coll]
(letfn [(step
[sep [f :as s] xs]
(if (or (not s) (pred f))
(cons [sep xs] (sift pred s))
(recur sep (next s) (conj xs f))))]
(lazy-seq
(when-let [s (seq coll)]
(step (first s) (next s) [])))))

As lazy as you can get, not holding unto the head (I hope), traversing
each element of the sequence only once.

Sincerely
Meikel

PS: Since the problem is ill-specified I assume, that the first item
is always a separator (for the implementors convenience). Which makes
sense, since nil does not necessarily fulfill pred and I don't another
"default" value.

Michał Marczyk

unread,
Jan 25, 2010, 7:03:32 AM1/25/10
to Clojure
Hi Group,

thought this nice puzzle would make a good occasion for a first
post. :-)

A solution to the original problem from c.l.s, with keywords replacing
symbols:

(ns sogaard-kata
(:use clojure.contrib.seq-utils))

(defn sogaard-kata [xs]
(map (fn [[k ys]] (into (vec k) (vec ys)))
(partition-all 2 (partition-by keyword? xs))))

(sogaard-kata [:a 1 2 3 :b 4 5 6 :c 7 8 9])
; -> ([:a 1 2 3] [:b 4 5 6] [:c 7 8 9])

This makes the assumption that the first item in the sequence is a
keyword; the problem seems underspecified otherwise.

All best,
Michał

Laurent PETIT

unread,
Jan 25, 2010, 10:29:19 AM1/25/10
to clo...@googlegroups.com
Hello,

So far, i've encountered the term of "kata" applied to software in a
somewhat similar sense as in the martial arts: very detailed
step-by-step explanation of how one things about the problem, solves
it bit by bit (does he first play with some functions at the REPL,
does he start to code from scratch -if so, what mental steps did he
made that was not materialized in a repl session -or documentation
browsing or whatever-).

*That* would make for interesting comparisons, I guess. But that's
much work to formalize than just playing golf, of course :-)

Would like to share this with you, because I thougth the name of the
post was a bit misleading, while still bringing to the table a way to
share knowledge that might be interesting for everybody which does not
have the chance to have a seasoned clojurer to peer program with.

examples of katas in java by uncle bob :
* bowling kata :
http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata ( direct
link to ppt: http://butunclebob.com/files/downloads/Bowling%20Game%20Kata.ppt
)
* primes factor kata :
http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata (direct
link to ppt: http://butunclebob.com/files/downloads/Prime%20Factors%20Kata.ppt
) (or as a video: http://katas.softwarecraftsmanship.org/?p=71 )

HTH,

--
Laurent

2010/1/25 Michał Marczyk <michal....@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

Message has been deleted

Laurent PETIT

unread,
Jan 25, 2010, 11:04:37 AM1/25/10
to clo...@googlegroups.com
ok, great ! :-)

2010/1/25 Sean Devlin <francoi...@gmail.com>:
> Laurent,
> This thread is a set up.  Specifically, I'm hoping these guys pick up
> the blog post:
>
> http://www.katacasts.com/
>
> I plan on posting a video in about a week going through everything.
> Demonstrate the power of the sequence abstraction, and the
> similarities of regexs and predicates.  Show how Clojure makes your
> life simple.
>
> Sean


>
> On Jan 25, 10:29 am, Laurent PETIT <laurent.pe...@gmail.com> wrote:
>> Hello,
>>
>> So far, i've encountered the term of "kata" applied to software in a
>> somewhat similar sense as in the martial arts: very detailed
>> step-by-step explanation of how one things about the problem, solves
>> it bit by bit (does he first play with some functions at the REPL,
>> does he start to code from scratch -if so, what mental steps did he
>> made that was not materialized in a repl session -or documentation
>> browsing or whatever-).
>>
>> *That* would make for interesting comparisons, I guess. But that's
>> much work to formalize than just playing golf, of course :-)
>>
>> Would like to share this with you, because I thougth the name of the
>> post was a bit misleading, while still bringing to the table a way to
>> share knowledge that might be interesting for everybody which does not
>> have the chance to have a seasoned clojurer to peer program with.
>>
>> examples of katas in java by uncle bob :

>>  * bowling kata :http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata( direct

>> 2010/1/25 Michał Marczyk <michal.marc...@gmail.com>:

Erik Price

unread,
Jan 28, 2010, 6:37:55 PM1/28/10
to Clojure
Thanks Sean, this was a great exercise. I'm comfortable reading
Clojure code, but writing it requires thinking differently from what I
am used to. My solution is clunky and less elegant than most of the
other submissions in this thread, but I avoided reading any of them
until I had implemented the solution myself, which was rewarding.

I welcome any criticism, especially where I could have used more
idiomatic Clojure.

http://gist.github.com/289274

e

Reply all
Reply to author
Forward
0 new messages