tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1,91 @@
import std.algorithm, std.array, std.typecons, std.range;
struct Spermutations(bool doCopy=true) {
private immutable uint n;
alias TResult = Tuple!(int[], int);
int opApply(in int delegate(in ref TResult) dg) {
int result;
int sign = 1;
alias Int2 = Tuple!(int, int);
auto p = iota(n).map!(i => Int2(i, i ? -1 : 0))().array();
TResult aux;
if (doCopy) {
aux[0] = p.map!(pp => pp[0])().array();
} else {
aux[0] = new int[n];
foreach (immutable i, immutable pp; p)
aux[0][i] = pp[0];
}
aux[1] = sign;
result = dg(aux);
if (result)
goto END;
while (p.canFind!(pp => pp[1])()) {
// Failed to use std.algorithm here, too much complex.
auto largest = Int2(-100, -100);
int i1 = -1;
foreach (immutable i, immutable pp; p) {
if (pp[1]) {
if (pp[0] > largest[0]) {
i1 = i;
largest = pp;
}
}
}
immutable n1 = largest[0], d1 = largest[1];
sign *= -1;
int i2;
if (d1 == -1) {
i2 = i1 - 1;
swap(p[i1], p[i2]);
if (i2 == 0 || p[i2 - 1][0] > n1)
p[i2][1] = 0;
} else if (d1 == 1) {
i2 = i1 + 1;
swap(p[i1], p[i2]);
if (i2 == n - 1 || p[i2 + 1][0] > n1)
p[i2][1] = 0;
}
if (doCopy) {
aux[0] = p.map!(pp => pp[0])().array();
} else {
foreach (immutable i, immutable pp; p)
aux[0][i] = pp[0];
}
aux[1] = sign;
result = dg(aux);
if (result)
goto END;
foreach (immutable i3, ref pp; p) {
immutable n3 = pp[0], d3 = pp[1];
if (n3 > n1)
pp[1] = (i3 < i2) ? 1 : -1;
}
}
END: return result;
}
}
Spermutations!doCopy spermutations(bool doCopy=true)(in uint n) {
return typeof(return)(n);
}
version (permutations_by_swapping1) {
void main() {
import std.stdio;
foreach (n; [3, 4]) {
writefln("\nPermutations and sign of %d items", n);
foreach (tp; spermutations(n))
writefln("Perm: %s Sign: %2d", tp.tupleof);
}
}
}

View file

@ -0,0 +1,34 @@
import std.algorithm, std.array, std.typecons, std.range;
Tuple!(int[], int)[] sPermutations(in int n) /*pure nothrow*/ {
static int[][] sPermu(in int items) /*pure nothrow*/ {
if (items <= 0)
return [[]];
typeof(return) r;
foreach (i, item; sPermu(items - 1)) {
if (i % 2)
r ~= iota(cast(int)item.length, -1, -1)
.map!(i => item[0..i] ~ (items-1) ~ item[i..$])()
.array();
else
r ~= iota(item.length + 1)
.map!(i => item[0..i] ~ (items-1) ~ item[i..$])()
.array();
}
return r;
}
auto r = sPermu(n);
return iota(r.length)
.map!(i => tuple(r[i], i % 2 ? -1 : 1))()
.array();
}
void main() {
import std.stdio;
foreach (n; [3, 4]) {
writefln("\nPermutations and sign of %d items", n);
foreach (tp; sPermutations(n))
writefln("Perm: %s Sign: %2d", tp.tupleof);
}
}