Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
41
Task/Best-shuffle/D/best-shuffle-1.d
Normal file
41
Task/Best-shuffle/D/best-shuffle-1.d
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
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[]);
|
||||
}
|
||||
}
|
||||
103
Task/Best-shuffle/D/best-shuffle-2.d
Normal file
103
Task/Best-shuffle/D/best-shuffle-2.d
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import std.stdio, std.algorithm, std.range;
|
||||
|
||||
extern(C) pure nothrow void* alloca(in size_t size);
|
||||
|
||||
void bestShuffle(in char[] txt, ref char[] result) pure nothrow {
|
||||
// Assume alloca to be pure.
|
||||
//extern(C) pure nothrow void* alloca(in size_t size);
|
||||
enum size_t NCHAR = size_t(char.max + 1);
|
||||
enum size_t MAX_VLA_SIZE = 1024;
|
||||
immutable size_t len = txt.length;
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
// txt and result must have the same length
|
||||
// allocate only when necessary
|
||||
if (result.length != len)
|
||||
result.length = len;
|
||||
|
||||
// how many of each character?
|
||||
size_t[NCHAR] counts;
|
||||
size_t fmax = 0;
|
||||
foreach (immutable char c; txt) {
|
||||
counts[c]++;
|
||||
if (fmax < counts[c])
|
||||
fmax = counts[c];
|
||||
}
|
||||
assert(fmax > 0 && fmax <= len);
|
||||
|
||||
// all character positions, grouped by character
|
||||
size_t[] ndx1;
|
||||
{
|
||||
size_t* ptr1;
|
||||
if ((len * size_t.sizeof) < MAX_VLA_SIZE)
|
||||
ptr1 = cast(size_t*)alloca(len * size_t.sizeof);
|
||||
// If alloca() has failed, or the memory needed is too much
|
||||
// large, then allocate from the heap.
|
||||
ndx1 = (ptr1 == null) ? new size_t[len] : ptr1[0 .. len];
|
||||
}
|
||||
{
|
||||
int pos = 0;
|
||||
foreach (immutable size_t ch; 0 .. NCHAR)
|
||||
if (counts[ch])
|
||||
foreach (j, char c; txt)
|
||||
if (c == ch) {
|
||||
ndx1[pos] = j;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
// regroup them for cycles
|
||||
size_t[] ndx2;
|
||||
{
|
||||
size_t* ptr2;
|
||||
if ((len * size_t.sizeof) < MAX_VLA_SIZE)
|
||||
ptr2 = cast(size_t*)alloca(len * size_t.sizeof);
|
||||
ndx2 = (ptr2 == null) ? new size_t[len] : ptr2[0 .. len];
|
||||
}
|
||||
{
|
||||
size_t n, m;
|
||||
foreach (immutable size_t i; 0 .. len) {
|
||||
ndx2[i] = ndx1[n];
|
||||
n += fmax;
|
||||
if (n >= len) {
|
||||
m++;
|
||||
n = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// How long can our cyclic groups be?
|
||||
immutable size_t grp = 1 + (len - 1) / fmax;
|
||||
|
||||
// How many of them are full length?
|
||||
immutable size_t lng = 1 + (len - 1) % fmax;
|
||||
|
||||
// Rotate each group.
|
||||
{
|
||||
size_t j;
|
||||
foreach (immutable size_t i; 0 .. fmax) {
|
||||
immutable size_t first = ndx2[j];
|
||||
immutable size_t glen = grp - (i < lng ? 0 : 1);
|
||||
foreach (immutable size_t k; 1 .. glen)
|
||||
ndx1[j + k - 1] = ndx2[j + k];
|
||||
ndx1[j + glen - 1] = first;
|
||||
j += glen;
|
||||
}
|
||||
}
|
||||
|
||||
// Result is original permuted according to our cyclic groups.
|
||||
foreach (immutable size_t i; 0 .. len)
|
||||
result[ndx2[i]] = txt[ndx1[i]];
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto data = ["abracadabra", "seesaw", "elk", "grrrrrr",
|
||||
"up", "a", "aabbbbaa", "", "xxxxx"];
|
||||
foreach (txt; data) {
|
||||
auto result = txt.dup;
|
||||
bestShuffle(txt, result);
|
||||
immutable nEqual = zip(txt, result).count!q{ a[0] == a[1] };
|
||||
writefln("%s, %s, (%d)", txt, result, nEqual);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue