Skip to content

Instantly share code, notes, and snippets.

@xsc
Created November 18, 2012 22:40
Show Gist options
  • Save xsc/4107920 to your computer and use it in GitHub Desktop.
Save xsc/4107920 to your computer and use it in GitHub Desktop.
Counting Characters in Clojure
(ns character-counter.main)
;; ------------------------------------------------------------------------
;;
;; SEE HERE: http://dev.xscheme.de/2012/11/counting-characters-in-clojure/
;;
;; ------------------------------------------------------------------------
;; Different Count Strategies
(def count-a-with-regex
(let [regex (re-pattern "^a*")]
(fn [string]
(count (re-find regex string)))))
(defn count-a-with-loop
[string]
(loop [characters string
a-count 0]
(if (= (first characters) \a)
(recur (rest characters) (inc a-count))
a-count)))
(defn count-a-with-reduce
[string]
(or (first
(reduce (fn [[a-count b?] character]
(if (and (not b?) (= character \a))
[(inc a-count)]
[a-count true]))
[0]
string))
0))
(defn count-a-with-take-while
[string]
(count (take-while #{\a} string)))
;; ------------------------------------------------------------------------
;; Evaluation
(defmacro time-it
[f s]
(let [n 100000]
`(let [s# ~s]
(println "Test" ~(str f))
(doseq [_# (range 5)]
(time (doseq [_# (range ~n)]
(~f s#))))
(println))))
(defn generate-str-seq
[a ca b cb]
(doall (concat (take ca (repeatedly (constantly a)))
(take cb (repeatedly (constantly b))))))
(defn -main
[]
(let [sq (generate-str-seq \a 128 \b 384)
s (apply str sq)]
(time-it count-a-with-regex s)
(time-it count-a-with-loop sq)
(time-it count-a-with-take-while sq))
(let [sq (generate-str-seq \b 384 \a 128)
s (apply str sq)]
(time-it count-a-with-regex s)
(time-it count-a-with-loop sq)
(time-it count-a-with-take-while sq)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment