Hi,

here my turn. Comments inline. Hope this helps.

Sincerely
Meikel

(defn f-to-seq
  [file]
  (with-open [rdr (java.io.BufferedReader.
                    (java.io.FileReader. file))]
    (doall (line-seq rdr))))
; Yes. doall is required here. Alternatively you can wrap the whole
thing
; in the with-open. Then you can process also larger files without
keeping
; all data in memory. YMMV.


(defn str-sort
  [string]
  (when string
    (apply str (sort string))))
; One can also skip the when here. Then nil input returns an empty
string.
; Whether that is better depends on the usage of the return value.
YMMV.
; (if (nil? x) x ...) is usually written as (when x ...).

(defn str-to-lower
  [string]
  (when string
    (.toLowerCase string)))

(defn anagram-add
  [anagrams akey word]
  (if (contains? anagrams akey)
    (-> anagrams
      (update-in [akey :count] inc)
      (update-in [akey :words] conj word))
    (assoc anagrams akey {:count 1 :words [word]})))
; I would prefer vectors over lists to store stuff. You get nice
; things for free, like O(1) appending, O(1) reverse, O(1) random
; access, ...

(defn word
  [s]
  (first s))
; or: (def word first)
; not needed for my solution

(def normalise (comp str-to-lower str-sort))

(defn build-anagrams
  [words]
  (reduce #(anagram-add %1 (normalise %2) %2) {} words))
; Looping with an accumulator, just returning the latter when the
; input is exhausted cries for reduce.

(defn print-anagram
  [v]
  (println (str (:count (second v)) " " (first v) ": " (:words (second
v)))))
; one could use destructuring to access things.

(defn print-anagram
  [anagram]
  (let [[normal-form {:keys [count words]}] anagram]
    (println (str count " " normal-form ": " words))))

(defn print-anagrams
  [ana]
  (doseq [v ana]
    (print-anagram v)))
; more descriptive names would be good, I guess

(defn anagram-key
  [elem]
  (- (:count (second elem))))
; the minus should take care of the reverse?

(def *words* (f-to-seq "/usr/share/dict/web2"))
(def *anagrams* (sort-by anagram-key (build-anagrams *words*)))
(print-anagrams (take 10 *anagrams*))

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