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,35 @@
import std.stdio, std.range, std.algorithm;
void throwDie(in uint nSides, in uint nDice, in uint s, uint[] counts)
pure nothrow @safe @nogc {
if (nDice == 0) {
counts[s]++;
return;
}
foreach (immutable i; 1 .. nSides + 1)
throwDie(nSides, nDice - 1, s + i, counts);
}
real beatingProbability(uint nSides1, uint nDice1,
uint nSides2, uint nDice2)()
pure nothrow @safe /*@nogc*/ {
uint[(nSides1 + 1) * nDice1] C1;
throwDie(nSides1, nDice1, 0, C1);
uint[(nSides2 + 1) * nDice2] C2;
throwDie(nSides2, nDice2, 0, C2);
immutable p12 = real((ulong(nSides1) ^^ nDice1) *
(ulong(nSides2) ^^ nDice2));
return cartesianProduct(C1[].enumerate, C2[].enumerate)
.filter!(p => p[0][0] > p[1][0])
.map!(p => real(p[0][1]) * p[1][1] / p12)
.sum;
}
void main() @safe {
writefln("%1.16f", beatingProbability!(4, 9, 6, 6));
writefln("%1.16f", beatingProbability!(10, 5, 7, 6));
}

View file

@ -0,0 +1,39 @@
import std.stdio, std.range, std.algorithm;
ulong[] combos(R)(R sides, in uint n) pure nothrow @safe
if (isForwardRange!R) {
if (sides.empty)
return null;
if (!n)
return [1];
auto ret = new typeof(return)(reduce!max(sides[0], sides[1 .. $]) * n + 1);
foreach (immutable i, immutable v; enumerate(combos(sides, n - 1))) {
if (!v)
continue;
foreach (immutable s; sides)
ret[i + s] += v;
}
return ret;
}
real winning(R)(R sides1, in uint n1, R sides2, in uint n2)
pure nothrow @safe if (isForwardRange!R) {
static void accumulate(T)(T[] arr) pure nothrow @safe @nogc {
foreach (immutable i; 1 .. arr.length)
arr[i] += arr[i - 1];
}
immutable p1 = combos(sides1, n1);
auto p2 = combos(sides2, n2);
immutable s = p1.sum * p2.sum;
accumulate(p2);
ulong win = 0; // 'win' is 1 beating 2.
foreach (immutable i, immutable x1; p1.dropOne.enumerate)
win += x1 * p2[min(i, $ - 1)];
return win / real(s);
}
void main() @safe {
writefln("%1.16f", winning(iota(1u, 5u), 9, iota(1u, 7u), 6));
writefln("%1.16f", winning(iota(1u, 11u), 5, iota(1u, 8u), 6));
}