Meikel's suggestions are all good and I would follow them. There are a number of built-in functions you can take advantage of if you're using 1.2 (they're also available in contrib for 1.1):
clojure.string/lower-case clojure.java.io/reader -- obviates java.io.BufferedReader and friends: (reader "/usr/share/dict/words") As a point of comparison, I did a similar code kata recently. I've posted it here, with a few lines added to show the top 10: http://gist.github.com/537945 It runs in a couple seconds on my machine. For maximum speed, transients might help. Justin On Aug 18, 6:46 pm, Damon Snyder <drsny...@gmail.com> wrote: > Hi Everyone, > I'm looking for some feedback on a small get-your-feet wet program I > wrote in clojure (my first). In particular, I hope to get feedback on > how to better make use of clojure's data structures and functional > programming in general. > > Below is the toy program and the sample output. It reads in words from > the OS X dictionary file, catalogs the anagrams, and then prints out > the top ten by frequency. Although performance is not my primary > concern here, it is a bit slow. It takes about 15s on my mac book > pro. > > As an example, is this the "proper" way to update multiple fields at > once in a nested hash-map: > > (update-in (update-in anagrams [akey :count] inc) [akey :words] conj > word))) > > I understand this as returning an copy of an updated copy of an > updated copy. > > Any feedback would be appreciated. Thanks, > Damon > > ## begin > (defn f-to-seq[file] > (with-open [rdr (java.io.BufferedReader. > (java.io.FileReader. file))] > (doall (line-seq rdr)))) > > (defn str-sort[str] > (if (nil? str) > str > (String. (into-array (. Character TYPE) (sort str))))) > > (defn str-to-lower[str] > (if (nil? str) > str > (.toLowerCase str))) > > (defn anagram-add[anagrams akey word] > (if (empty? (get anagrams akey)) > (assoc anagrams akey (hash-map :count 1, :words (list word))) > (update-in (update-in anagrams [akey :count] inc) [akey :words] > conj word))) > > (defn word[seq] (first seq)) > > (defn build-anagrams[seq] > (loop [seq seq > akey (str-sort (str-to-lower (word seq))) > anagrams {}] > (if (empty? seq) > anagrams > (recur (rest seq) > (str-sort (str-to-lower (word (rest seq)))) > (anagram-add anagrams akey (word seq)))))) > > (defn print-anagram[v] > (println (str (:count (first (rest v))) " " (first v) ": " (:words > (first (rest v)))))) > > (defn print-anagrams[ana] > (doseq [v ana] > (print-anagram v))) > > (defn anagram-key[elem] (:count (first (rest elem)))) > > (def *words* (f-to-seq "/usr/share/dict/web2")) > (def *anagrams* (sort-by anagram-key (build-anagrams *words*))) > (print-anagrams (take 10 (reverse *anagrams*))) > > ## output > 11 agnor: ("Ronga" "rogan" "organ" "orang" "Orang" "nagor" "groan" > "grano" "goran" "argon" "angor") > 10 aelps: ("speal" "spale" "slape" "sepal" "saple" "salep" "Pales" > "Lepas" "lapse" "Elaps") > 9 eerst: ("tsere" "terse" "stree" "stere" "steer" "reset" "reest" > "estre" "ester") > 9 aeerst: ("teaser" "staree" "seater" "saeter" "reseat" "Eastre" > "easter" "Easter" "asteer") > 9 aacinr: ("narica" "crania" "Crania" "carina" "Carian" "canari" > "Canari" "arnica" "acinar") > 9 acert: ("trace" "recta" "react" "creta" "creat" "crate" "cater" > "carte" "caret") > 8 ailr: ("rial" "rail" "lira" "liar" "lari" "Lari" "lair" "aril") > 8 aelpt: ("tepal" "pleat" "plate" "petal" "pelta" "patel" "palet" > "leapt") > 8 airst: ("Trias" "tisar" "tarsi" "stria" "stair" "sitar" "astir" > "arist") > 8 aemrt: ("Trema" "trame" "terma" "tamer" "ramet" "metra" "mater" > "armet") -- 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