Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,31 @@
|
|||
import std.stdio, std.random, std.algorithm, std.traits, std.array;
|
||||
|
||||
enum DutchColors { red, white, blue }
|
||||
|
||||
void dutchNationalFlagSort(DutchColors[] items) pure nothrow @nogc {
|
||||
int lo, mid, hi = items.length - 1;
|
||||
|
||||
while (mid <= hi)
|
||||
final switch (items[mid]) {
|
||||
case DutchColors.red:
|
||||
swap(items[lo++], items[mid++]);
|
||||
break;
|
||||
case DutchColors.white:
|
||||
mid++;
|
||||
break;
|
||||
case DutchColors.blue:
|
||||
swap(items[mid], items[hi--]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
DutchColors[12] balls;
|
||||
foreach (ref ball; balls)
|
||||
ball = uniform!DutchColors;
|
||||
|
||||
writeln("Original Ball order:\n", balls);
|
||||
balls.dutchNationalFlagSort;
|
||||
writeln("\nSorted Ball Order:\n", balls);
|
||||
assert(balls[].isSorted, "Balls not sorted.");
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import std.stdio, std.random, std.algorithm, std.range,
|
||||
std.array, std.traits;
|
||||
|
||||
/*
|
||||
This implementation has less requirements, it works with just
|
||||
a Bidirectional Range instead of a Random Access Range.
|
||||
|
||||
(Comments modified from "Notes on Programming" by Alexander
|
||||
Stepanov.)
|
||||
|
||||
Let us assume that somehow we managed to solve the problem up
|
||||
to some middle point s:
|
||||
|
||||
0000001111?????22222222
|
||||
^ ^ ^
|
||||
f s l (first, second, last)
|
||||
|
||||
If s points to an item with value 0 (red) we swap it with an
|
||||
element pointed at by f and advance both f and s.
|
||||
If s refers to an item 1 (white) we just advance s.
|
||||
If s refers to an item 2 (blue) we swap elements
|
||||
pointed by l and s and we decrement l.
|
||||
|
||||
In D/Phobos we use Ranges, that are like pairs of iterators.
|
||||
So 'secondLast' represents the s and l iterators, and the 'first'
|
||||
range contains f plus an unused end.
|
||||
|
||||
secondLast represents the inclusive range of items not yet seen.
|
||||
When it's empty, the algorithm has finished.
|
||||
|
||||
Loop variant: in each iteration of the for loop the length of
|
||||
secondLast decreases by 1. So the algorithm terminates.
|
||||
*/
|
||||
void dutchNationalFlagSort(Range, T)(Range secondLast,
|
||||
in T lowVal, in T highVal)
|
||||
pure nothrow if (isBidirectionalRange!Range &&
|
||||
hasSwappableElements!Range &&
|
||||
is(ElementType!Range == T)) {
|
||||
for (auto first = secondLast; !secondLast.empty; )
|
||||
if (secondLast.front == lowVal) {
|
||||
swap(first.front, secondLast.front);
|
||||
first.popFront();
|
||||
secondLast.popFront();
|
||||
} else if (secondLast.front == highVal) {
|
||||
swap(secondLast.front, secondLast.back);
|
||||
secondLast.popBack();
|
||||
} else
|
||||
secondLast.popFront();
|
||||
}
|
||||
|
||||
void main() {
|
||||
enum DutchColors { red, white, blue }
|
||||
DutchColors[12] balls;
|
||||
foreach (ref ball; balls)
|
||||
ball = [EnumMembers!DutchColors][uniform(0, $)];
|
||||
|
||||
writeln("Original Ball order:\n", balls);
|
||||
balls[].dutchNationalFlagSort(DutchColors.red,
|
||||
DutchColors.blue);
|
||||
writeln("\nSorted Ball Order:\n", balls);
|
||||
assert(balls[].isSorted(), "Balls not sorted");
|
||||
|
||||
// More tests:
|
||||
foreach (i; 0 .. 100_000) {
|
||||
int n = uniform(0, balls.length);
|
||||
foreach (ref ball; balls[0 .. n])
|
||||
ball = [EnumMembers!DutchColors][uniform(0, $)];
|
||||
balls[0 .. n].dutchNationalFlagSort(DutchColors.red,
|
||||
DutchColors.blue);
|
||||
assert(balls[0 .. n].isSorted());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
import std.stdio, std.random, std.algorithm, std.traits, std.range;
|
||||
|
||||
enum Color : ubyte { blue, white, red }
|
||||
|
||||
immutable isMonochrome = (in Color[] a, in size_t i, in size_t j, in Color c)
|
||||
pure nothrow @safe @nogc => iota(i, j).all!(k => a[k] == c);
|
||||
|
||||
bool isPermutation(in Color[] a1, in Color[] a2) pure nothrow @safe @nogc {
|
||||
size_t[EnumMembers!Color.length] counts1, counts2;
|
||||
foreach (immutable x; a1)
|
||||
counts1[x]++;
|
||||
foreach (immutable x; a2)
|
||||
counts2[x]++;
|
||||
return counts1 == counts2;
|
||||
}
|
||||
|
||||
|
||||
void dutchNationalFlagSort(Color[] a) pure nothrow @safe @nogc
|
||||
// This function is not @nogc in -debug builds.
|
||||
/*
|
||||
Scan of the array 'a' from left to right using 'i' and we
|
||||
maintain this invariant, using indices 'b' and 'r':
|
||||
|
||||
0 b i r
|
||||
+---------+----------+-----------+-------+
|
||||
| blue | white | ? | red |
|
||||
+---------+----------+-----------+-------+
|
||||
*/
|
||||
out {
|
||||
// Find b and r.
|
||||
immutable bRaw = a.countUntil!q{a != b}(Color.blue);
|
||||
immutable size_t b = (bRaw == -1) ? a.length : bRaw;
|
||||
immutable rRaw = a.retro.countUntil!q{a != b}(Color.red);
|
||||
immutable size_t r = (rRaw == -1) ? 0 : (a.length - rRaw);
|
||||
|
||||
assert(isMonochrome(a, 0, b, Color.blue));
|
||||
assert(isMonochrome(a, b, r, Color.white));
|
||||
assert(isMonochrome(a, r, a.length, Color.red));
|
||||
// debug assert(isPermutation(a, a.old));
|
||||
} body {
|
||||
size_t b = 0, i = 0, r = a.length;
|
||||
debug {
|
||||
/*ghost*/ immutable aInit = a.idup; // For loop invariant.
|
||||
/*ghost*/ size_t riPred = r - i; // For loop variant.
|
||||
}
|
||||
|
||||
while (i < r) {
|
||||
/*invariant*/ assert(0 <= b && b <= i && i <= r && r <= a.length);
|
||||
/*invariant*/ assert(isMonochrome(a, 0, b, Color.blue));
|
||||
/*invariant*/ assert(isMonochrome(a, b, i, Color.white));
|
||||
/*invariant*/ assert(isMonochrome(a, r, a.length, Color.red));
|
||||
/*invariant*/ debug assert(isPermutation(a, aInit));
|
||||
|
||||
final switch (a[i]) with (Color) {
|
||||
case blue:
|
||||
a[b].swap(a[i]);
|
||||
b++;
|
||||
i++;
|
||||
break;
|
||||
case white:
|
||||
i++;
|
||||
break;
|
||||
case red:
|
||||
r--;
|
||||
a[r].swap(a[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
debug {
|
||||
/*variant*/ assert((r - i) < riPred);
|
||||
riPred = r - i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
Color[12] balls;
|
||||
|
||||
// Test special cases.
|
||||
foreach (immutable color; [EnumMembers!Color]) {
|
||||
balls[] = color;
|
||||
balls.dutchNationalFlagSort;
|
||||
assert(balls[].isSorted, "Balls not sorted.");
|
||||
}
|
||||
|
||||
foreach (ref b; balls)
|
||||
b = uniform!Color;
|
||||
|
||||
writeln("Original Ball order:\n", balls);
|
||||
balls.dutchNationalFlagSort;
|
||||
writeln("\nSorted Ball Order:\n", balls);
|
||||
assert(balls[].isSorted, "Balls not sorted.");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue