Last active
July 6, 2019 07:50
-
-
Save rrrnld/9371c82e7bd0437dab6b72d15f2c0b5a to your computer and use it in GitHub Desktop.
Unfinished Clojure puzzle for the purely functional newsletter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user=> (require '[clojure.string :as str]) | |
nil | |
user=> (def dictionary (->> (slurp "/home/arne/Downloads/purely functional - wordlist.txt") | |
#_=> (str/split-lines))) | |
#'user/dictionary | |
user=> (defn frequency-histogram [phrase] | |
#_=> (->> (str/split (str/lower-case phrase) #"\s+") | |
#_=> (map frequencies) | |
#_=> (apply merge-with +))) | |
#'user/frequency-histogram | |
user=> (defn fits-perfectly? [p1 p2] | |
#_=> (->> (merge-with - (frequency-histogram p1) (frequency-histogram p2)) | |
#_=> (vals) | |
#_=> (every? zero?))) | |
#'user/fits-perfectly? | |
user=> (defn fits-in-phrase? [phrase1 phrase2] | |
#_=> (let [freq1 (frequency-histogram phrase1) | |
#_=> freq2 (frequency-histogram phrase2)] | |
#_=> (every? (fn [[k v]] | |
#_=> (>= (get freq1 k 0) v)) freq2))) | |
#'user/fits-in-phrase? | |
user=> (defn find-anagram | |
#_=> [phrase] | |
#_=> (let [dictionary (filter (partial fits-in-phrase? phrase) dictionary)] | |
#_=> (loop [word (nth dictionary 0) | |
#_=> candidates dictionary | |
#_=> anagram [] | |
#_=> found [] | |
#_=> next-start 1] | |
#_=> (cond | |
#_=> ;; as long as our list of candidates isn't completely used up... | |
#_=> (some? word) | |
#_=> (let [guess (str/join " " (conj anagram word))] | |
#_=> (cond | |
#_=> ;; found an anagram :) | |
#_=> (fits-perfectly? phrase guess) | |
#_=> (recur (first candidates) dictionary anagram (conj found (conj anagram word)) | |
#_=> | |
#_=> ;; might still find one | |
#_=> (fits-in-phrase? phrase guess) | |
#_=> (recur (first candidates) dictionary (conj anagram word) found next-start) | |
#_=> | |
#_=> ;; the current word doesn't fit | |
#_=> :else | |
#_=> (recur (first candidates) (rest candidates) anagram found next-start))) | |
#_=> | |
#_=> ;; try again from a blank anagram if we weren't sucessful | |
#_=> (< next-start (count dictionary)) | |
#_=> (recur (nth dictionary next-start) dictionary [] found (inc next-start))) | |
#_=> | |
#_=> ;; we did everything we could :) | |
#_=> :else found)))) | |
#'user/find-anagram | |
;; TODO: Find all anagrams, not just the first one alphabetically |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment