Skip to content

Instantly share code, notes, and snippets.

@KGZM
Last active August 29, 2015 14:23
Show Gist options
  • Save KGZM/c37be596f5adc997f990 to your computer and use it in GitHub Desktop.
Save KGZM/c37be596f5adc997f990 to your computer and use it in GitHub Desktop.
Simple markov chain implementation
(ns markov.experiment
(:require [clojure.string :as string]))
(defn wrand [m]
(let [total (reduce + (vals m))
r (rand total)]
(loop [ks (keys m) sum 0]
(if (< r (+ (get m (first ks))
sum))
(first ks)
(recur (rest ks)
(+ (get m (first ks))
sum))))))
(defn make-markov
([text] (make-markov text {}))
([text chain]
(reduce (fn [state [curr next]]
(update-in state [curr next] (fnil inc 0)))
chain
(map (fn [a b] [a b])
text
(drop 1 text)))))
(defn run-markov
([chain length]
(run-markov chain length (rand-nth (keys chain))))
([chain length seed]
(loop [output seed
seed seed
left length]
(if (zero? left)
output
(let [new (wrand (get chain seed))]
(recur (str output " " new) new (dec left)))))))
(defn words [text] (-> text (string/replace #"\s+" " ") (string/split #" ")))
(defn prepare [text] (words (string/lower-case text)))
(comment
(def corpus (make-markov (prepare some-text)))
(run-markov corpus 128))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment