Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
130
Task/Stable-marriage-problem/D/stable-marriage-problem-1.d
Normal file
130
Task/Stable-marriage-problem/D/stable-marriage-problem-1.d
Normal 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");
|
||||
}
|
||||
119
Task/Stable-marriage-problem/D/stable-marriage-problem-2.d
Normal file
119
Task/Stable-marriage-problem/D/stable-marriage-problem-2.d
Normal 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue