Hello,
On Mon, Sep 14, 2009 at 11:48 PM, ajuc <[email protected]> wrote:
>
> Hello, I'm new in clojure and lisp, and I have problem with making
> this code elegant (or at least short).
>
> This is Floyd-Warshall algorithm - very simple algorithm in imperative
> form (3 nested for loops).
>
> In clojure the best I've get so far is this monstrosity:
[snip]
> How to do this the Right Way?
>
You are "accumulating" a result, which hints us at 'reduce.
And 'for provides the nested enumeration:
(defn floyd-warshall2 [{:keys [nodes distances]}]
(reduce (fn [[distances prevs] [k x y]]
(let [d (+ (distances [x k] Double/POSITIVE_INFINITY)
(distances [k y] Double/POSITIVE_INFINITY))]
(if (< d (distances [x y] Double/POSITIVE_INFINITY))
[(assoc distances [x y] d) (assoc prevs [x y] k)]
[distances prevs])))
[distances {}] (for [k nodes x nodes y nodes] [k x y])))
You should refrain from using indices or counters: most of the time, you can
directly test a sequence. Why to maintain a counter to know whe you reach
the end of a coll when (seq s) gives us this information and (next s)
"decrements" the counter. (see
http://clj-me.blogspot.com/2009/05/counting-without-numbers.html)
Christophe
--
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---