Skip to content

Instantly share code, notes, and snippets.

@maxcountryman
Created March 18, 2012 13:11
Show Gist options
  • Save maxcountryman/2072019 to your computer and use it in GitHub Desktop.
Save maxcountryman/2072019 to your computer and use it in GitHub Desktop.
Weasel in Clojure
;; weasel
(def TARGET "ME THINKS IT IS LIKE A WEASEL")
(def ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ ")
(def RATE 0.05)
(def rand-seed
"Generate a random seed as long as the target."
(take (count TARGET) (repeatedly #(rand-nth ALPHABET))))
(defn mutate?
"Mutates a string `s` if rand is less than the rate."
[c]
(if (< (rand) RATE) (rand-nth ALPHABET) c))
(defn check-fitness
"Checks the fitness of a string `s` against the target. Returns 0 for
perfect matches, otherwise a postive integer."
[s]
(count (filter #(not= (first %) (last %)) (map list s TARGET))))
(defn generate-candidate
"Generates a candidate over a seed `s`."
[s]
(let [candidate (map mutate? s)]
{:score (check-fitness candidate), :candidate candidate}))
(defn best-candidate
"Finds the best candidate in a pool of `n`."
[seed n]
(apply min-key :score (take n (repeatedly #(generate-candidate seed)))))
(defn run-weasel
"Runs a pool of `n` number of candidates and loops until a match is found."
[n]
(loop [generation 0 seed rand-seed]
(let [candidate (best-candidate seed n)]
(println generation (apply str (:candidate candidate)))
(if (zero? (:score candidate))
nil
(recur (inc generation) (:candidate candidate))))))
@maxcountryman
Copy link
Author

Run with:

(run-weasel 1000)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment