What would you think of this form of coding ? - The rationale is to separate functions that deal with system "boundaries" from "core algorithmic functions". So you should at least have two functions : one that does not deal with input/output formats : will only deal with clojure/java constructs. - Don't expose "too early" functions that are just here to simplify the algorithm : there's already the possibility to use defn- , but there's also the possibility to embed functions in the principal function by using let and inner functions - And I also tried to write the "core algorithmic function" as "functional" as I can. Do you think the functional version is more ore less "obfuscated" ?
Here would be the "core function" (taking a string as an input, and outputting the sorted sequence of ["word" 2] vectors) : (defn topwords [str] "Takes a string as an input, and returns a sequence of vectors of pairs [word nb-of-word-occurences]" (let [words (let [ls (System/getProperty "line.separator")] #(.split % ls)) freqs (partial reduce #(merge-with + %1 {%2 1}) {}) sort (partial sort-by (comp - val))] (-> str words freqs sort))) HTH, -- Laurent On Dec 26, 4:37 pm, lpetit <laurent.pe...@gmail.com> wrote: > Instead of #(- (val %)), one could also use the compose function : > (comp - val) > > My 0,02 EURO, > > -- > Laurent > > On Dec 25, 4:58 pm, Mibu <mibu.cloj...@gmail.com> wrote: > > > My version: > > > (defn top-words [input-filename result-filename] > > (spit result-filename > > (apply str > > (map #(format "%s : %d\n" (first %) (second %)) > > (sort-by #(-(val %)) > > (reduce #(conj %1 { %2 (inc (%1 %2 0)) }) {} > > (map #(.toLowerCase %) > > (re-seq #"\w+" > > (slurp > > input-filename))))))))) > > > Mibu > > > On Dec 25, 2:16 pm, Piotr 'Qertoip' Włodarek <qert...@gmail.com> > > wrote: > > > > Given the input text file, the program should write to disk a ranking > > > of words sorted by frequency, like: > > > > the : 52483 > > > and : 32558 > > > of : 23477 > > > a : 22486 > > > to : 21993 > > > > My first implementation: > > > > (defn topwords [in-filepath, out-filepath] > > > (def words (.split (.toLowerCase (slurp in-filepath)) "\\s+")) > > > > (spit out-filepath > > > (apply str > > > (concat > > > (map (fn [pair] (format "%20s : %5d \r\n" (key pair) > > > (val pair))) > > > (sort-by #( -(val %) ) > > > (reduce > > > (fn [counted-words word] > > > ( assoc counted-words > > > word > > > (inc (get counted-words > > > word 0)) )) > > > {} > > > words))) > > > ["\r\n"])))) > > > > Somehow I feel it's far from optimal. Could you please advise and > > > improve? What is the best, idiomatic implementation of this simple > > > problem? > > > > regards, > > > Piotrek --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---