41 lines
1.1 KiB
D
41 lines
1.1 KiB
D
import std.stdio, std.random, std.algorithm, std.conv, std.range,
|
|
std.traits, std.typecons;
|
|
|
|
auto bestShuffle(S)(in S orig) @safe if (isSomeString!S) {
|
|
static if (isNarrowString!S)
|
|
immutable o = orig.dtext;
|
|
else
|
|
alias o = orig;
|
|
|
|
auto s = o.dup;
|
|
s.randomShuffle;
|
|
|
|
foreach (immutable i, ref ci; s) {
|
|
if (ci != o[i])
|
|
continue;
|
|
foreach (immutable j, ref cj; s)
|
|
if (ci != cj && ci != o[j] && cj != o[i]) {
|
|
swap(ci, cj);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return tuple(s, s.zip(o).count!q{ a[0] == a[1] });
|
|
} unittest {
|
|
assert("abracadabra".bestShuffle[1] == 0);
|
|
assert("immediately".bestShuffle[1] == 0);
|
|
assert("grrrrrr".bestShuffle[1] == 5);
|
|
assert("seesaw".bestShuffle[1] == 0);
|
|
assert("pop".bestShuffle[1] == 1);
|
|
assert("up".bestShuffle[1] == 0);
|
|
assert("a".bestShuffle[1] == 1);
|
|
assert("".bestShuffle[1] == 0);
|
|
}
|
|
|
|
void main(in string[] args) @safe {
|
|
if (args.length > 1) {
|
|
immutable entry = args.dropOne.join(' ');
|
|
const res = entry.bestShuffle;
|
|
writefln("%s : %s (%d)", entry, res[]);
|
|
}
|
|
}
|