Instantly share code, notes, and snippets.

Embed
What would you like to do?
(ns markov.core)
(defn transform
[words]
(->> words
(partition 2 1)
(reduce (fn [acc [w next-w]]
(update-in acc
[w next-w]
(fnil inc 0)))
{})))
(defn markers [line]
(concat [:start]
(clojure.string/split line #"\s+")
[:end]))
(defn lazy-lines [file]
(letfn [(helper [rdr]
(lazy-seq
(if-let [line (.readLine rdr)]
(concat (markers line) (helper rdr))
(do (.close rdr) nil))))]
(helper (clojure.java.io/reader file))))
(defn wrand
"given a vector of slice sizes, returns the index of a slice given a
random spin of a roulette wheel with compartments proportional to
slices."
[slices]
(let [total (reduce + slices)
r (rand total)]
(loop [i 0 sum 0]
(if (< r (+ (slices i) sum))
i
(recur (inc i) (+ (slices i) sum))))))
(defn generate-sentence [data]
(loop [ws (data :start)
acc []]
(let [v (vec (vals ws))
i (wrand v)
w (nth (keys ws) i)
nws (data w)]
(if (= :end w)
(clojure.string/join " " acc)
(recur nws (concat acc [w]))))))
(defn -main [& args]
(let [markov (transform (lazy-lines (first args)))]
(generate-sentence markov)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment