RosettaCodeData/Task/Best-shuffle/YAMLScript/best-shuffle.ys

46 lines
907 B
Plaintext

!YS-v0
defn main(*inputs):
each input inputs: !:say
apply format '%s, %s, (%d)':
best-shuffle(input)
defn best-shuffle(s):
ref =: s:group-indices:cycles
prm =: concat.apply(map(partial(rotate 1) ref))
ref =: concat(ref*)
map(vector ref prm):
.sort-by(first _)
.map(second)
.map(partial(get s))
.str(*)
.call(\([s _ s.score(_)]) _)
defn score(before after):
map(== before after)
.filter(true?).#
defn group-indices(s):
map-indexed(vector s)
.merge-vecs({}):vals
.sort-by(count _):reverse
defn cycles(coll):
n =: coll.0.#
cycle =: range(n):cycle
coll =: concat(coll*)
map(vector coll cycle):
.merge-vecs([])
defn rotate(n coll):
c =: coll.#
n =: (c + n) % c
concat coll.drop(n): coll.take(n)
defn merge-vecs(vecs init):
reduce _ init vecs:
fn(counts [index x]):
assoc counts x:
counts.$x.or([]).conj(index)