(use 'clojure.contrib.combinatorics
'clojure.contrib.str-utils)
(defn anagrams [xs]
(map #(str-join "" %) (distinct (permutations xs))))
Of course, the real meat is in the permutations function. The
implementation in the combinatorics library is a bit complicated.
Here's something simpler (and slower):
(defn splittings [xs]
(lazy-seq
(cons [() xs]
(when (seq xs)
(map (fn [[left right]]
[(cons (first xs) left) right])
(splittings (rest xs)))))))
(defn permutations [xs]
(if (seq xs)
(for [perm (permutations (rest xs))
[left right] (splittings perm)]
(concat left [(first xs)] right))
[()]))
On Mon, Apr 19, 2010 at 8:20 AM, verec
<[email protected]> wrote:
> I have two problems with the following code.
> First, I have this `tos' business (to-string) because:
> user=> (first "abc")
> \a
> user=> (rest "abc")
> (\b \c)
> Since I wanted to get strings out of strings, a character or a
> collection is no good.
>
> Second, I ended-up having to use a mutable atom `res' because I
> couldn't figure out how to do it otherwise.
>
> Any pointer on how to tackle either or both problems welcome.
>
> (ns word-play)
>
> (defn rotate
> "Take a collection and left rotates it n steps.
> If n is negative, the collection is rotated right.
> Executes in O(n) time."
> ([coll]
> (rotate 1 coll))
> ([n coll]
> (let [c (count coll)]
> (take c (drop (mod n c) (cycle coll))))))
>
> (defn all-rotations [word]
> "all rots"
> (take (count (str word)) (cycle (iterate rotate (str word)))))
>
> (defn anagram [word]
> "To generate all anagrams of a given string of length n, the most
> obvious solution is to consider all n rotations of the string one
> by one, and for each such rotation, concatenate its first character
> with each of the anagrams of the new string composed of all but its
> first character."
> (cond
> (= (count word) 0) '("")
> (= (count word) 1) (list word)
> true
> (let [all (all-rotations word)
> tos #(str (reduce str %))
> wst (map tos all)
> res (atom "")]
> (doseq [w wst]
> (let [s (str w)
> f (str (first (str s)))
> n (str (tos (next (str s))))
> j #(str f (tos %))
> a (ana3 n)
> r (map j a)]
> (swap! res concat r)))
> �...@res)))
>
> user=> (anagram "1")
> ("1")
> user=> (anagram "12")
> ("12" "21")
> user=> (anagram "123")
> ("123" "132" "231" "213" "312" "321")
> user=> (anagram "lisp")
> ("lisp" "lips" "lspi" "lsip" "lpis" "lpsi" "ispl" "islp" "ipls" "ipsl"
> "ilsp" "ilps" "spli" "spil" "slip" "slpi" "sipl" "silp" "plis" "plsi"
> "pisl" "pils" "psli" "psil")
> user=>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en