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,65 @@
import std.stdio, std.algorithm, std.typecons, std.array,
std.conv, std.range, std.traits;
auto derangements(in size_t n, in bool countOnly=false)
/*pure nothrow*/ {
size_t[] seq = iota(n).array();
auto ori = seq.idup;
size_t[][] all;
size_t cnt = n == 0;
foreach (tot; 0 .. fact(n)-1) {
size_t j = n - 2;
while (seq[j] > seq[j + 1])
j--;
size_t k = n - 1;
while (seq[j] > seq[k])
k--;
swap(seq[k], seq[j]);
size_t r = n - 1;
size_t s = j + 1;
while (r > s) {
swap(seq[s], seq[r]);
r--;
s++;
}
j = 0;
while (j < n && seq[j] != ori[j])
j++;
if (j == n) {
if (countOnly)
cnt++;
else
all ~= seq.dup;
}
}
return tuple(all, cnt);
}
T fact(T)(in T n) pure nothrow {
Unqual!T result = 1;
for (Unqual!T i = 2; i <= n; i++)
result *= i;
return result;
}
T subfact(T)(in T n) pure nothrow {
if (0 <= n && n <= 2)
return n != 1;
return (n - 1) * (subfact(n - 1) + subfact(n - 2));
}
void main() {
writeln("derangements for n = 4\n");
foreach (d; derangements(4)[0])
writeln(d);
writeln("\ntable of n vs counted vs calculated derangements\n");
foreach (i; 0 .. 10)
writefln("%s %-7s%-7s", i, derangements(i, 1)[1], subfact(i));
writefln("\n!20 = %s", subfact(20L));
}

View file

@ -0,0 +1,47 @@
import std.stdio, std.algorithm, std.typecons, std.array,
std.conv, std.range, std.traits;
auto derangementsR(in size_t n, in bool countOnly=false) {
auto seq = iota(n).array();
immutable ori = seq.idup;
const(size_t[])[] res;
size_t cnt;
void perms(in size_t[] s, in size_t[] pre=null) nothrow {
if (s.length) {
foreach (i, c; s)
perms(s[0 .. i] ~ s[i + 1 .. $], pre ~ c);
} else if (mismatch!q{a != b}(pre, ori)[0].length == 0) {
if (countOnly) cnt++;
else res ~= pre;
}
}
perms(seq);
return tuple(res, cnt);
}
T fact(T)(in T n) pure nothrow {
Unqual!T result = 1;
for (Unqual!T i = 2; i <= n; i++)
result *= i;
return result;
}
T subfact(T)(in T n) pure nothrow {
if (0 <= n && n <= 2)
return n != 1;
return (n - 1) * (subfact(n - 1) + subfact(n - 2));
}
void main() {
writeln("derangements for n = 4\n");
foreach (const d; derangementsR(4)[0])
writeln(d);
writeln("\ntable of n vs counted vs calculated derangements\n");
foreach (i; 0 .. 10)
writefln("%s %-7s%-7s", i, derangementsR(i,1)[1], subfact(i));
writefln("\n!20 = %s", subfact(20L));
}