Here's my version. Main points:
* Use with-open & line-seq for worry-free laziness
* Do everything in one swoop (reduce)
* Perform one regexp match per line
* Leverage ->>
;;
(ns user
(use [clojure.java.io :only [reader]]))
(def re-vote #"([A-z]{1,16})(\+\+|\-\-)")
(defn extract-votes
[line]
(map rest (re-seq re-vote line)))
(defn reckon
[log]
(with-open [r (reader log)]
(let [votes (mapcat extract-votes (line-seq r))]
(reduce
(fn [tally [nick vote]]
(let [inc-or-dec (if (= vote "++") inc dec)]
(assoc tally nick (inc-or-dec (tally nick 0)))))
{}
votes))))
(defn -main [& [[log]]]
(let [tally (->> log
reckon
(remove (comp zero? val))
(sort-by (comp - val)))]
(doseq [[nick score] tally]
(println nick score))))
Hope that helps,
Justin
On Dec 21, 8:38 pm, Marek Kubica <[email protected]> wrote:
> Hi,
>
> I wrote a small log file analyzer for IRC logs. We use nickname++ and
> nickname-- to track the "karma", so after trying to write it in
> JavaScript (failed due to to the fact that Gjs/Seed are unmature yet),
> Factor (failed because I am just too stupid to understand it), Guile
> (failed because I ran into encoding/regex-problems), so I gave Clojure
> a try.
>
> I really liked the immutable data stuctures, so I tried to avoid
> mutation.
>
> So uhm, this is my first Clojure program. I tend to learn a lot from
> code reviews and would be happy if someone could take a look at it and
> tell me what to improve and how to write more idiomatic code.
>
> Code is here, and reproduced below:
> <https://github.com/Leonidas-from-XIV/karmawhore/blob/68ff6b681c5862fa...>
>
> Thanks in advance!
>
> regards,
> Marek
>
> (ns net.xivilization.karmawhore
> (:gen-class)
> (:use [clojure.contrib.duck-streams :only (read-lines)]))
>
> (def allowed-nickname "[A-z]{1,16}")
> (def nick-plus (re-pattern (format "(%s)\\+\\+" allowed-nickname)))
> (def nick-minus (re-pattern (format "(%s)\\-\\-" allowed-nickname)))
>
> (defn extract-nicks [regexp line]
> (map second (re-seq regexp line)))
>
> (defn modify-karma [op h nick]
> (let [current-value (h nick)]
> (if (nil? current-value) (assoc h nick (op 1))
> (assoc h nick (op current-value 1)))))
>
> (def increase-karma (partial modify-karma +))
> (def decrease-karma (partial modify-karma -))
>
> (defn process-line [acc line]
> (let [nicks-add (extract-nicks nick-plus line)
> nicks-sub (extract-nicks nick-minus line)
> after-add (reduce increase-karma acc nicks-add)]
> (reduce decrease-karma after-add nicks-sub)))
>
> (defn -main [& args]
> (let [file-name (first (first args))
> histogram (reduce process-line (hash-map) (read-lines
> file-name)) nonzero? (comp not zero? second)
> histogram (filter nonzero? histogram)
> sorted-by-karma (sort-by #(- (second %)) histogram)]
> (doseq [item sorted-by-karma]
> (printf "%s %d\n" (first item) (second item)))))
>
> (-main *command-line-args*)
--
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