Skip to content

Instantly share code, notes, and snippets.

@elarkin
Created July 23, 2014 20:21
Show Gist options
  • Save elarkin/f46041c088e30b504cb3 to your computer and use it in GitHub Desktop.
Save elarkin/f46041c088e30b504cb3 to your computer and use it in GitHub Desktop.
Anagram Detection in Clojure
(ns clojure-anagram.core
(:use [clojure [string :only [split-lines join]]]))
(def words (-> "/Users/you-will-never-guess/misc-src/anagram-jam/4000words.txt"
slurp
split-lines))
(defn single-word-anagrams-for [word]
(let [normalized-word (sort word)]
(filter #(= (sort %) normalized-word) words)))
(def make-pool (memoize (fn [word]
(dissoc (frequencies word) \space))))
(defn shrink-word-list [pool word-list]
(filter (fn [word]
(let [word-pool (make-pool word)]
(every? #(and (contains? pool %)
(<= (get word-pool %) (get pool %))) (keys word-pool)))) word-list))
(defn anagrams-for-helper [pool word-list]
(let [shrunk-word-list (shrink-word-list pool word-list)]
(if (zero? (count shrunk-word-list))
[]
(mapcat (fn [candidate]
(let [smaller-pool (merge-with - pool (make-pool candidate))
anagrams-with-candidate (anagrams-for-helper smaller-pool shrunk-word-list)]
(if (zero? (apply + (vals smaller-pool)))
[[candidate]]
(map #(sort (conj % candidate)) anagrams-with-candidate)))
) shrunk-word-list))))
(defn anagrams-for [phrase]
(let [pool (make-pool phrase)]
(distinct (map #(join \space %) (anagrams-for-helper pool words)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment