Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,13 @@
T[][] comb(T)(in T[] arr, in int k) pure nothrow {
if (k == 0) return [[]];
typeof(return) result;
foreach (immutable i, immutable x; arr)
foreach (suffix; arr[i + 1 .. $].comb(k - 1))
result ~= x ~ suffix;
return result;
}
void main() {
import std.stdio;
[0, 1, 2, 3].comb(2).writeln;
}

View file

@ -0,0 +1,11 @@
import std.stdio, std.algorithm, std.range;
immutable(int)[][] comb(immutable int[] s, in int m) pure nothrow @safe {
if (!m) return [[]];
if (s.empty) return [];
return s[1 .. $].comb(m - 1).map!(x => s[0] ~ x).array ~ s[1 .. $].comb(m);
}
void main() {
4.iota.array.comb(2).writeln;
}

View file

@ -0,0 +1,94 @@
module combinations3;
import std.traits: Unqual;
struct Combinations(T, bool copy=true) {
Unqual!T[] pool, front;
size_t r, n;
bool empty = false;
size_t[] indices;
size_t len;
bool lenComputed = false;
this(T[] pool_, in size_t r_) pure nothrow @safe {
this.pool = pool_.dup;
this.r = r_;
this.n = pool.length;
if (r > n)
empty = true;
indices.length = r;
foreach (immutable i, ref ini; indices)
ini = i;
front.length = r;
foreach (immutable i, immutable idx; indices)
front[i] = pool[idx];
}
@property size_t length() /*logic_const*/ pure nothrow @nogc {
static size_t binomial(size_t n, size_t k) pure nothrow @safe @nogc
in {
assert(n > 0, "binomial: n must be > 0.");
} body {
if (k < 0 || k > n)
return 0;
if (k > (n / 2))
k = n - k;
size_t result = 1;
foreach (size_t d; 1 .. k + 1) {
result *= n;
n--;
result /= d;
}
return result;
}
if (!lenComputed) {
// Set cache.
len = binomial(n, r);
lenComputed = true;
}
return len;
}
void popFront() pure nothrow @safe {
if (!empty) {
bool broken = false;
size_t pos = 0;
foreach_reverse (immutable i; 0 .. r) {
pos = i;
if (indices[i] != i + n - r) {
broken = true;
break;
}
}
if (!broken) {
empty = true;
return;
}
indices[pos]++;
foreach (immutable j; pos + 1 .. r)
indices[j] = indices[j - 1] + 1;
static if (copy)
front = new Unqual!T[front.length];
foreach (immutable i, immutable idx; indices)
front[i] = pool[idx];
}
}
}
Combinations!(T, copy) combinations(bool copy=true, T)
(T[] items, in size_t k)
in {
assert(items.length, "combinations: items can't be empty.");
} body {
return typeof(return)(items, k);
}
// Compile with -version=combinations3_main to run main.
version(combinations3_main)
void main() {
import std.stdio, std.array, std.algorithm;
[1, 2, 3, 4].combinations!false(2).array.writeln;
[1, 2, 3, 4].combinations!true(2).array.writeln;
[1, 2, 3, 4].combinations(2).map!(x => x).writeln;
}

View file

@ -0,0 +1,100 @@
module combinations4;
import std.stdio, std.algorithm, std.conv;
ulong choose(int n, int k) nothrow
in {
assert(n >= 0 && k >= 0, "choose: no negative input.");
} body {
static ulong[][] cache;
if (n < k)
return 0;
else if (n == k)
return 1;
while (n >= cache.length)
cache ~= [1UL]; // = choose(m, 0);
auto kmax = min(k, n - k);
while(kmax >= cache[n].length) {
immutable h = cache[n].length;
cache[n] ~= choose(n - 1, h - 1) + choose(n - 1, h);
}
return cache[n][kmax];
}
int largestV(in int p, in int q, in long r) nothrow
in {
assert(p > 0 && q >= 0 && r >= 0, "largestV: no negative input.");
} body {
auto v = p - 1;
while (choose(v, q) > r)
v--;
return v;
}
struct Comb {
immutable int n, m;
@property size_t length() const /*nothrow*/ {
return to!size_t(choose(n, m));
}
int[] opIndex(in size_t idx) const {
if (m < 0 || n < 0)
return [];
if (idx >= length)
throw new Exception("Out of bound");
ulong x = choose(n, m) - 1 - idx;
int a = n, b = m;
auto res = new int[m];
foreach (i; 0 .. m) {
a = largestV(a, b, x);
x = x - choose(a, b);
b = b - 1;
res[i] = n - 1 - a;
}
return res;
}
int opApply(int delegate(ref int[]) dg) const {
int[] yield;
foreach (i; 0 .. length) {
yield = this[i];
if (dg(yield))
break;
}
return 0;
}
static auto On(T)(in T[] arr, in int m) {
auto comb = Comb(arr.length, m);
return new class {
@property size_t length() const /*nothrow*/ {
return comb.length;
}
int opApply(int delegate(ref T[]) dg) const {
auto yield = new T[m];
foreach (c; comb) {
foreach (idx; 0 .. m)
yield[idx] = arr[c[idx]];
if (dg(yield))
break;
}
return 0;
}
};
}
}
version(combinations4_main)
void main() {
foreach (c; Comb.On([1, 2, 3], 2))
writeln(c);
}