54 lines
1.2 KiB
Clojure
54 lines
1.2 KiB
Clojure
(defn score [before after]
|
|
(->> (map = before after)
|
|
(filter true? ,)
|
|
count))
|
|
|
|
(defn merge-vecs [init vecs]
|
|
(reduce (fn [counts [index x]]
|
|
(assoc counts x (conj (get counts x []) index)))
|
|
init vecs))
|
|
|
|
(defn frequency
|
|
"Returns a collection of indecies of distinct items"
|
|
[coll]
|
|
(->> (map-indexed vector coll)
|
|
(merge-vecs {} ,)))
|
|
|
|
(defn group-indecies [s]
|
|
(->> (frequency s)
|
|
vals
|
|
(sort-by count ,)
|
|
reverse))
|
|
|
|
(defn cycles [coll]
|
|
(let [n (count (first coll))
|
|
cycle (cycle (range n))
|
|
coll (apply concat coll)]
|
|
(->> (map vector coll cycle)
|
|
(merge-vecs [] ,))))
|
|
|
|
(defn rotate [n coll]
|
|
(let [c (count coll)
|
|
n (rem (+ c n) c)]
|
|
(concat (drop n coll) (take n coll))))
|
|
|
|
(defn best-shuffle [s]
|
|
(let [ref (cycles (group-indecies s))
|
|
prm (apply concat (map (partial rotate 1) ref))
|
|
ref (apply concat ref)]
|
|
(->> (map vector ref prm)
|
|
(sort-by first ,)
|
|
(map second ,)
|
|
(map (partial get s) ,)
|
|
(apply str ,)
|
|
(#(vector s % (score s %))))))
|
|
|
|
user> (->> ["abracadabra" "seesaw" "elk" "grrrrrr" "up" "a"]
|
|
(map best-shuffle ,)
|
|
vec)
|
|
[["abracadabra" "bdabararaac" 0]
|
|
["seesaw" "eawess" 0]
|
|
["elk" "lke" 0]
|
|
["grrrrrr" "rgrrrrr" 5]
|
|
["up" "pu" 0]
|
|
["a" "a" 1]]
|