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,130 @@
import std.stdio, std.array, std.algorithm, std.string;
string[string] matchmaker(string[][string] guyPrefers,
string[][string] girlPrefers) /*@safe*/ {
string[string] engagedTo;
string[] freeGuys = guyPrefers.keys;
while (freeGuys.length) {
const string thisGuy = freeGuys[0];
freeGuys.popFront();
const auto thisGuyPrefers = guyPrefers[thisGuy];
foreach (girl; thisGuyPrefers) {
if (girl !in engagedTo) { // girl is free
engagedTo[girl] = thisGuy;
break;
} else {
string otherGuy = engagedTo[girl];
string[] thisGirlPrefers = girlPrefers[girl];
if (thisGirlPrefers.countUntil(thisGuy) <
thisGirlPrefers.countUntil(otherGuy)) {
// this girl prefers this guy to
// the guy she's engagedTo to.
engagedTo[girl] = thisGuy;
freeGuys ~= otherGuy;
break;
}
// else no change, keep looking for this guy
}
}
}
return engagedTo;
}
bool check(bool doPrint=false)(string[string] engagedTo,
string[][string] guyPrefers,
string[][string] galPrefers) @safe {
enum MSG = "%s likes %s better than %s and %s " ~
"likes %s better than their current partner";
string[string] inverseEngaged;
foreach (k, v; engagedTo)
inverseEngaged[v] = k;
foreach (she, he; engagedTo) {
auto sheLikes = galPrefers[she];
auto sheLikesBetter = sheLikes[0 .. sheLikes.countUntil(he)];
auto heLikes = guyPrefers[he];
auto heLikesBetter = heLikes[0 .. heLikes.countUntil(she)];
foreach (guy; sheLikesBetter) {
auto guysGirl = inverseEngaged[guy];
auto guyLikes = guyPrefers[guy];
if (guyLikes.countUntil(guysGirl) >
guyLikes.countUntil(she)) {
static if (doPrint)
writefln(MSG, she, guy, he, guy, she);
return false;
}
}
foreach (gal; heLikesBetter) {
auto girlsGuy = engagedTo[gal];
auto galLikes = galPrefers[gal];
if (galLikes.countUntil(girlsGuy) >
galLikes.countUntil(he)) {
static if (doPrint)
writefln(MSG, he, gal, she, gal, he);
return false;
}
}
}
return true;
}
void main() /*@safe*/ {
auto guyData = "abe abi eve cath ivy jan dee fay bea hope gay
bob cath hope abi dee eve fay bea jan ivy gay
col hope eve abi dee bea fay ivy gay cath jan
dan ivy fay dee gay hope eve jan bea cath abi
ed jan dee bea cath fay eve abi ivy hope gay
fred bea abi dee gay eve ivy cath jan hope fay
gav gay eve ivy bea cath abi dee hope jan fay
hal abi eve hope fay ivy cath jan bea gay dee
ian hope cath dee gay bea abi fay ivy jan eve
jon abi fay jan gay eve bea dee cath ivy hope";
auto galData = "abi bob fred jon gav ian abe dan ed col hal
bea bob abe col fred gav dan ian ed jon hal
cath fred bob ed gav hal col ian abe dan jon
dee fred jon col abe ian hal gav dan bob ed
eve jon hal fred dan abe gav col ed ian bob
fay bob abe ed ian jon dan fred gav col hal
gay jon gav hal fred bob abe col ed dan ian
hope gav jon bob abe ian dan hal ed col fred
ivy ian col hal gav fred bob abe ed jon dan
jan ed hal gav abe bob jon col ian fred dan";
string[][string] guyPrefers, galPrefers;
foreach (line; guyData.splitLines())
guyPrefers[split(line)[0]] = split(line)[1..$];
foreach (line; galData.splitLines())
galPrefers[split(line)[0]] = split(line)[1..$];
writeln("Engagements:");
auto engagedTo = matchmaker(guyPrefers, galPrefers);
writeln("\nCouples:");
string[] parts;
foreach (k; engagedTo.keys.sort())
writefln("%s is engagedTo to %s", k, engagedTo[k]);
writeln();
bool c = check!(true)(engagedTo, guyPrefers, galPrefers);
writeln("Marriages are ", c ? "stable" : "unstable");
writeln("\n\nSwapping two fiances to introduce an error");
auto gals = galPrefers.keys.sort();
swap(engagedTo[gals[0]], engagedTo[gals[1]]);
foreach (gal; gals[0 .. 2])
writefln(" %s is now engagedTo to %s", gal, engagedTo[gal]);
writeln();
c = check!(true)(engagedTo, guyPrefers, galPrefers);
writeln("Marriages are ", c ? "stable" : "unstable");
}

View file

@ -0,0 +1,119 @@
import std.stdio, std.algorithm, std.array;
enum F { abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan }
enum M { abe, bob, col, dan, ed, fred, gav, hal, ian, jon }
alias PrefMapF = M[][F];
alias PrefMapM = F[][M];
alias Couples = M[F];
immutable PrefMapF womenPref;
immutable PrefMapM menPref;
static this() pure nothrow @safe {
with (F) with (M) {
womenPref = [
abi: [bob, fred, jon, gav, ian, abe, dan, ed, col, hal],
bea: [bob, abe, col, fred, gav, dan, ian, ed, jon, hal],
cath: [fred, bob, ed, gav, hal, col, ian, abe, dan, jon],
dee: [fred, jon, col, abe, ian, hal, gav, dan, bob, ed],
eve: [jon, hal, fred, dan, abe, gav, col, ed, ian, bob],
fay: [bob, abe, ed, ian, jon, dan, fred, gav, col, hal],
gay: [jon, gav, hal, fred, bob, abe, col, ed, dan, ian],
hope: [gav, jon, bob, abe, ian, dan, hal, ed, col, fred],
ivy: [ian, col, hal, gav, fred, bob, abe, ed, jon, dan],
jan: [ed, hal, gav, abe, bob, jon, col, ian, fred, dan]
];
menPref = [
abe: [abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay],
bob: [cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay],
col: [hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan],
dan: [ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi],
ed: [jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay],
fred: [bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay],
gav: [gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay],
hal: [abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee],
ian: [hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve],
jon: [abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope]
];
}
}
/// Does 'first' appear before 'second' in preference list?
bool prefers(T)(in T[] preference, in T first, in T second)
pure nothrow @safe @nogc if (is(T == F) || is(T == M)) {
//const found = preference.findAmong([first, second]);
immutable T[2] two = [first, second];
const found = preference.findAmong(two[]);
return !(found.empty || found.front == second);
}
void checkStability(in Couples engaged, in PrefMapM menPref,
in PrefMapF womenPref) @safe {
"Stablility:".writeln;
bool stable = true;
foreach (immutable bride, immutable groom; engaged) {
const prefList = menPref[groom];
foreach (immutable pr; prefList) {
if (pr == bride) // He prefers his bride.
break;
if (prefers(prefList, pr, bride) &&
// He prefers another woman.
prefers(womenPref[pr], groom, engaged[pr])) {
// Other woman prefers him.
writeln("\t", pr, " prefers ", groom, " over ",
engaged[pr], " and ", groom, " prefers ",
pr, " over ", bride);
stable = false;
}
}
}
if (stable)
"\t(all marriages stable)".writeln;
}
void main() /*@safe*/ {
auto bachelors = menPref.keys.sort().release;// No queue in Phobos.
Couples engaged;
"Matchmaking:".writeln;
while (!bachelors.empty) {
immutable suitor = bachelors[0];
bachelors.popFront;
immutable prefList = menPref[suitor];
foreach (immutable bride; prefList) {
if (bride !in engaged) { // She's available.
writeln("\t", bride, " and ", suitor);
engaged[bride] = suitor; // Hook up.
break;
}
immutable groom = engaged[bride];
if (prefers(womenPref[bride], suitor, groom)) {
writeln("\t", bride, " dumped ", groom,
" for ", suitor);
bachelors ~= groom; // Dump that zero.
engaged[bride] = suitor; // Get a hero.
break;
}
}
}
"Engagements:".writeln;
foreach (immutable first, immutable second; engaged)
writeln("\t", first, " and ", second);
checkStability(engaged, menPref, womenPref);
"Perturb:".writeln;
engaged[F.abi].swap(engaged[F.bea]);
writeln("\tengage abi with ", engaged[F.abi],
" and bea with ", engaged[F.bea]);
checkStability(engaged, menPref, womenPref);
}