Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -43,3 +43,5 @@ And a complete list of ranked preferences, where the most liked is to the left:
|
|||
# [http://www.cs.columbia.edu/~evs/intro/stable/writeup.html The Stable Marriage Problem]. (Eloquent description and background information).
|
||||
# [http://sephlietz.com/gale-shapley/ Gale-Shapley Algorithm Demonstration].
|
||||
# [http://mathsite.math.berkeley.edu/smp/smp.html Another Gale-Shapley Algorithm Demonstration].
|
||||
# [https://www.youtube.com/watch?v=Qcv1IqHWAzg Stable Marriage Problem - Numberphile] (Video).
|
||||
# [https://www.youtube.com/watch?v=LtTV6rIxhdo Stable Marriage Problem (the math bit)] (Video).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
PERSON.CFC
|
||||
|
||||
component displayName="Person" accessors="true" {
|
||||
property name="Name" type="string";
|
||||
property name="MrOrMrsGoodEnough" type="Person";
|
||||
property name="UnrealisticExpectations" type="array";
|
||||
property name="PersonalHistory" type="array";
|
||||
|
||||
public Person function init( required String name ) {
|
||||
setName( arguments.name );
|
||||
setPersonalHistory([ getName() & " is on the market." ]);
|
||||
this.HotnessScale = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Boolean function hasSettled() {
|
||||
// if we have settled, return true;
|
||||
return isInstanceOf( getMrOrMrsGoodEnough(), "Person" );
|
||||
}
|
||||
|
||||
public Person function getBestOfWhatIsLeft() {
|
||||
// increment the hotness scale...1 is best, 10 is...well...VERY settling.
|
||||
this.HotnessScale++;
|
||||
// get the match from the current rung in the barrel
|
||||
var bestChoice = getUnrealisticExpectations()[ this.HotnessScale ];
|
||||
return bestChoice;
|
||||
}
|
||||
|
||||
public Boolean function wouldRatherBeWith( required Person person ) {
|
||||
// only compare if we've already settled on a potential mate
|
||||
if( isInstanceOf( this.getMrOrMrsGoodEnough(), "Person" ) ) {
|
||||
// if the new person's hotness is greater (numerically smaller) than our current beau...
|
||||
return getHotness( this, arguments.person ) < getHotness( this, this.getMrOrMrsGoodEnough() );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Void function settle( required Person person ) {
|
||||
if( person.hasSettled() ) {
|
||||
// this is the match we want. Force a break up of a previous relationship (sorry!)
|
||||
dumpLikeATonOfBricks( person );
|
||||
}
|
||||
person.setMrOrMrsGoodEnough( this );
|
||||
if( hasSettled() ) {
|
||||
// this is the match we want, so write a dear john to our current match
|
||||
dumpLikeATonOfBricks( this );
|
||||
}
|
||||
logHookup( arguments.person );
|
||||
// we've found the mate of our dreams!
|
||||
setMrOrMrsGoodEnough( arguments.person );
|
||||
}
|
||||
|
||||
public Void function swing( required Person person ) {
|
||||
// get our spouses
|
||||
var mySpouse = getMrOrMrsGoodEnough();
|
||||
var notMySpouse = arguments.person.getMrOrMrsGoodEnough();
|
||||
// swap em'
|
||||
setMrOrMrsGoodEnough( notMySpouse );
|
||||
person.setMrOrMrsGoodEnough( mySpouse );
|
||||
}
|
||||
|
||||
public Void function dumpLikeATonOfBricks( required Person person ) {
|
||||
logBreakup( arguments.person );
|
||||
person.getMrOrMrsGoodEnough().setMrOrMrsGoodEnough( JavaCast( "null", "" ) );
|
||||
}
|
||||
|
||||
public String function psychoAnalyze() {
|
||||
logNuptuals();
|
||||
logRegrets();
|
||||
var personalJourney = "";
|
||||
for( var entry in getPersonalHistory() ) {
|
||||
personalJourney = personalJourney & entry & "<br />";
|
||||
}
|
||||
return personalJourney;
|
||||
}
|
||||
|
||||
private Numeric function getHotness( required Person pursuer, required Person pursued ) {
|
||||
var pursuersExpectations = pursuer.getUnrealisticExpectations();
|
||||
var hotnessFactor = 1;
|
||||
for( var hotnessFactor=1; hotnessFactor<=arrayLen( pursuersExpectations ); hotnessFactor++ ) {
|
||||
if( pursuersExpectations[ hotnessFactor ].getName()==arguments.pursued.getName() ) {
|
||||
return hotnessFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Void function logRegrets() {
|
||||
var spouse = getMrOrMrsGoodEnough();
|
||||
var spouseHotness = getHotness( this, spouse );
|
||||
var myHotness = getHotness( spouse, this );
|
||||
if( spouseHotness == 1 && myHotness == 1 ) {
|
||||
arrayAppend( getPersonalHistory(), "Yes, yes, the beautiful people always find happy endings: #getName()# (her ###myHotness#), #spouse.getName()# (his ###spouseHotness#)");
|
||||
}
|
||||
else if( spouseHotness == myHotness ) {
|
||||
arrayAppend( getPersonalHistory(), "#getName()# (her ###myHotness#) was made for #spouse.getName()# (his ###spouseHotness#). How precious.");
|
||||
}
|
||||
else if( spouseHotness > myHotness ) {
|
||||
arrayAppend( getPersonalHistory(), "#getName()# (her ###myHotness#) could have done better than #spouse.getName()# (his ###spouseHotness#). Poor slob.");
|
||||
}
|
||||
else {
|
||||
arrayAppend( getPersonalHistory(), "#getName()# (her ###myHotness#) is a lucky bastard to have landed #spouse.getName()# (his ###spouseHotness#).");
|
||||
}
|
||||
}
|
||||
|
||||
private Void function logNuptuals() {
|
||||
arrayAppend( getPersonalHistory(), "#getName()# has settled for #getMrOrMrsGoodEnough().getName()#." );
|
||||
}
|
||||
|
||||
private Void function logHookup( required Person person ) {
|
||||
var winnerHotness = getHotness( this, arguments.person );
|
||||
var myHotness = getHotness( arguments.person, this );
|
||||
arrayAppend( getPersonalHistory(), "#getName()# (her ###myHotness#) is checking out #arguments.person.getName()# (his ###winnerHotness#), but wants to keep his options open.");
|
||||
}
|
||||
|
||||
private Void function logBreakup( required Person person ) {
|
||||
var scrub = person.getMrOrMrsGoodEnough();
|
||||
var scrubHotness = getHotness( person, scrub );
|
||||
var myHotness = getHotness( person, this );
|
||||
arrayAppend( getPersonalHistory(), "#getName()# is so hot (her ###myHotness#) that #person.getName()# is dumping #scrub.getName()# (her ###scrubHotness#)");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
INDEX.CFM
|
||||
|
||||
<cfscript>
|
||||
/**
|
||||
* Let's get these crazy kids married!
|
||||
* @men.hint The men who want to get married
|
||||
*/
|
||||
function doCreepyMassMarriages( required Array men ) {
|
||||
marriagesAreStable = false;
|
||||
while( !marriagesAreStable ) {
|
||||
marriagesAreStable = true;
|
||||
for( man in men ) {
|
||||
if( !man.hasSettled() ) {
|
||||
marriagesAreStable = false;
|
||||
sexyLady = man.getBestOfWhatIsLeft();
|
||||
if( !sexyLady.hasSettled() || sexyLady.wouldRatherBeWith( man ) ) {
|
||||
man.settle( sexyLady );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return men;
|
||||
}
|
||||
|
||||
/**
|
||||
* We played God...now let's see if society is going to survive
|
||||
* @men.hint The married men
|
||||
* @women.hint The married women
|
||||
*/
|
||||
function isSocietyStable( required Array men, required Array women ) {
|
||||
// loop over married men
|
||||
for( var man in arguments.men ) {
|
||||
// loop over married women
|
||||
for( var woman in arguments.women ) {
|
||||
// if the man does not prefer this woman to his current spouse, and the women
|
||||
// doesn't prefer the man to her current spouse, this is the best possible match
|
||||
if( man.wouldRatherBeWith( woman ) && woman.wouldRatherBeWith( man ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// the men
|
||||
abe = new Person( "Abe" );
|
||||
bob = new Person( "Bob" );
|
||||
col = new Person( "Col" );
|
||||
dan = new Person( "Dan" );
|
||||
ed = new Person( "Ed" );
|
||||
fred = new Person( "Fred" );
|
||||
gav = new Person( "Gav" );
|
||||
hal = new Person( "Hal" );
|
||||
ian = new Person( "Ian" );
|
||||
jon = new Person( "Jon" );
|
||||
|
||||
men = [ abe, bob, col, dan, ed, fred, gav, hal, ian, jon ];
|
||||
|
||||
// the women
|
||||
abi = new Person( "Abi" );
|
||||
bea = new Person( "Bea" );
|
||||
cath = new Person( "Cath" );
|
||||
dee = new Person( "Dee" );
|
||||
eve = new Person( "Eve" );
|
||||
fay = new Person( "Fay" );
|
||||
gay = new Person( "Gay" );
|
||||
hope = new Person( "Hope" );
|
||||
ivy = new Person( "Ivy" );
|
||||
jan = new Person( "Jan" );
|
||||
|
||||
women = [ abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan ];
|
||||
|
||||
// set unrealistic expectations for the men
|
||||
abe.setUnrealisticExpectations([ abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay ]);
|
||||
bob.setUnrealisticExpectations([ cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay ]);
|
||||
col.setUnrealisticExpectations([ hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan ]);
|
||||
dan.setUnrealisticExpectations([ ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi ]);
|
||||
ed.setUnrealisticExpectations([ jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay ]);
|
||||
fred.setUnrealisticExpectations([ bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay ]);
|
||||
gav.setUnrealisticExpectations([ gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay ]);
|
||||
hal.setUnrealisticExpectations([ abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee ]);
|
||||
ian.setUnrealisticExpectations([ hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve ]);
|
||||
jon.setUnrealisticExpectations([ abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope ]);
|
||||
// set unrealistic expectations for the women
|
||||
abi.setUnrealisticExpectations([ bob, fred, jon, gav, ian, abe, dan, ed, col, hal ]);
|
||||
bea.setUnrealisticExpectations([ bob, abe, col, fred, gav, dan, ian, ed, jon, hal ]);
|
||||
cath.setUnrealisticExpectations([ fred, bob, ed, gav, hal, col, ian, abe, dan, jon ]);
|
||||
dee.setUnrealisticExpectations([ fred, jon, col, abe, ian, hal, gav, dan, bob, ed ]);
|
||||
eve.setUnrealisticExpectations([ jon, hal, fred, dan, abe, gav, col, ed, ian, bob ]);
|
||||
fay.setUnrealisticExpectations([ bob, abe, ed, ian, jon, dan, fred, gav, col, hal ]);
|
||||
gay.setUnrealisticExpectations([ jon, gav, hal, fred, bob, abe, col, ed, dan, ian ]);
|
||||
hope.setUnrealisticExpectations([ gav, jon, bob, abe, ian, dan, hal, ed, col, fred ]);
|
||||
ivy.setUnrealisticExpectations([ ian, col, hal, gav, fred, bob, abe, ed, jon, dan ]);
|
||||
jan.setUnrealisticExpectations([ ed, hal, gav, abe, bob, jon, col, ian, fred, dan ]);
|
||||
|
||||
// here comes the bride, duhn, duhn, duh-duhn
|
||||
possiblyHappilyMarriedMen = doCreepyMassMarriages( men );
|
||||
// let's see who shacked up!
|
||||
for( man in possiblyHappilyMarriedMen ) {
|
||||
writeoutput( man.psychoAnalyze() & "<br />" );
|
||||
}
|
||||
// check if society is stable
|
||||
if( isSocietyStable( men, women ) ) {
|
||||
writeoutput( "Hey, look at that. Creepy social engineering works. Sort of...<br /><br />" );
|
||||
}
|
||||
// what happens if couples start swingin'?
|
||||
jon.swing( fred );
|
||||
writeoutput( "Swapping Jon and Fred's wives...will society survive?<br /><br />" );
|
||||
// check if society is still stable after the swingers
|
||||
if( !isSocietyStable( men, women ) ) {
|
||||
writeoutput( "Nope, now everything is broken. Sharing spouses doesn't work, kids.<br />" );
|
||||
}
|
||||
</cfscript>
|
||||
|
|
@ -2,7 +2,7 @@ import std.stdio, std.array, std.algorithm, std.string;
|
|||
|
||||
|
||||
string[string] matchmaker(string[][string] guyPrefers,
|
||||
string[][string] girlPrefers) {
|
||||
string[][string] girlPrefers) /*@safe*/ {
|
||||
string[string] engagedTo;
|
||||
string[] freeGuys = guyPrefers.keys;
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ string[string] matchmaker(string[][string] guyPrefers,
|
|||
|
||||
bool check(bool doPrint=false)(string[string] engagedTo,
|
||||
string[][string] guyPrefers,
|
||||
string[][string] galPrefers) {
|
||||
string[][string] galPrefers) @safe {
|
||||
enum MSG = "%s likes %s better than %s and %s " ~
|
||||
"likes %s better than their current partner";
|
||||
string[string] inverseEngaged;
|
||||
|
|
@ -77,7 +77,7 @@ bool check(bool doPrint=false)(string[string] engagedTo,
|
|||
}
|
||||
|
||||
|
||||
void main() {
|
||||
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
|
||||
|
|
@ -111,7 +111,7 @@ void main() {
|
|||
|
||||
writeln("\nCouples:");
|
||||
string[] parts;
|
||||
foreach (k; engagedTo.keys.sort)
|
||||
foreach (k; engagedTo.keys.sort())
|
||||
writefln("%s is engagedTo to %s", k, engagedTo[k]);
|
||||
writeln();
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ void main() {
|
|||
writeln("Marriages are ", c ? "stable" : "unstable");
|
||||
|
||||
writeln("\n\nSwapping two fiances to introduce an error");
|
||||
auto gals = galPrefers.keys.sort;
|
||||
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]);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ alias Couples = M[F];
|
|||
immutable PrefMapF womenPref;
|
||||
immutable PrefMapM menPref;
|
||||
|
||||
pure nothrow static this() {
|
||||
static this() pure nothrow @safe {
|
||||
with (F) with (M) {
|
||||
womenPref = [
|
||||
abi: [bob, fred, jon, gav, ian, abe, dan, ed, col, hal],
|
||||
|
|
@ -42,13 +42,15 @@ pure nothrow static this() {
|
|||
|
||||
/// Does 'first' appear before 'second' in preference list?
|
||||
bool prefers(T)(in T[] preference, in T first, in T second)
|
||||
pure nothrow if (is(T == F) || is(T == M)) {
|
||||
const found = preference.findAmong([first, 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) {
|
||||
in PrefMapF womenPref) @safe {
|
||||
"Stablility:".writeln;
|
||||
bool stable = true;
|
||||
foreach (immutable bride, immutable groom; engaged) {
|
||||
|
|
@ -74,7 +76,7 @@ void checkStability(in Couples engaged, in PrefMapM menPref,
|
|||
"\t(all marriages stable)".writeln;
|
||||
}
|
||||
|
||||
void main() {
|
||||
void main() /*@safe*/ {
|
||||
auto bachelors = menPref.keys.sort().release;// No queue in Phobos.
|
||||
Couples engaged;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
@end
|
||||
|
||||
@implementation Person
|
||||
+ (Person *)named:(NSString *)name {
|
||||
return [[Person alloc] initWithName:name];
|
||||
+ (instancetype)named:(NSString *)name {
|
||||
return [[self alloc] initWithName:name];
|
||||
}
|
||||
- (id)initWithName:(NSString *)name {
|
||||
- (instancetype)initWithName:(NSString *)name {
|
||||
if ((self = [super init])) {
|
||||
_name = name;
|
||||
_prefs = nil;
|
||||
|
|
@ -98,7 +98,7 @@ void doMarriage() {
|
|||
ivy.prefs = @[ ian, col, hal, gav, fred, bob, abe, ed, jon, dan ];
|
||||
jan.prefs = @[ ed, hal, gav, abe, bob, jon, col, ian, fred, dan ];
|
||||
|
||||
NSArray *men = [NSArray arrayWithArray:abi.prefs];
|
||||
NSArray *men = abi.prefs;
|
||||
|
||||
NSUInteger freeMenCount = men.count;
|
||||
while (freeMenCount > 0) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
my %he-likes =
|
||||
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 >,
|
||||
;
|
||||
|
||||
my %she-likes =
|
||||
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 >,
|
||||
;
|
||||
|
||||
my \guys = %he-likes.keys;
|
||||
my \gals = %she-likes.keys;
|
||||
|
||||
my %fiancé;
|
||||
my %fiancée;
|
||||
my %proposed;
|
||||
|
||||
sub she-prefers ($her, $hottie) { .index($hottie) < .index(%fiancé{$her}) given ~%she-likes{$her} }
|
||||
sub he-prefers ($him, $hottie) { .index($hottie) < .index(%fiancée{$him}) given ~%he-likes{$him} }
|
||||
|
||||
match'em;
|
||||
check-stability;
|
||||
|
||||
perturb'em;
|
||||
check-stability;
|
||||
|
||||
sub match'em { #'
|
||||
say 'Matchmaking:';
|
||||
while unmatched-guy() -> $guy {
|
||||
my $gal = preferred-choice($guy);
|
||||
%proposed{"$guy $gal"} = '❤';
|
||||
if not %fiancé{$gal} {
|
||||
engage($guy, $gal);
|
||||
say "\t$gal and $guy";
|
||||
}
|
||||
elsif she-prefers($gal, $guy) {
|
||||
my $engaged-guy = %fiancé{$gal};
|
||||
engage($guy, $gal);
|
||||
%fiancée{$engaged-guy} = '';
|
||||
say "\t$gal dumped $engaged-guy for $guy";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub check-stability {
|
||||
my @instabilities = gather for guys X gals -> $m, $w {
|
||||
if he-prefers($m, $w) and she-prefers($w, $m) {
|
||||
take "\t$w prefers $m to %fiancé{$w} and $m prefers $w to %fiancée{$m}";
|
||||
}
|
||||
}
|
||||
|
||||
say 'Stablility:';
|
||||
if @instabilities {
|
||||
.say for @instabilities;
|
||||
}
|
||||
else {
|
||||
say "\t(all marriages stable)";
|
||||
}
|
||||
}
|
||||
|
||||
sub unmatched-guy { guys.first: { not %fiancée{$_} } }
|
||||
|
||||
sub preferred-choice($guy) { %he-likes{$guy}.first: { not %proposed{"$guy $_" } } }
|
||||
|
||||
sub engage($guy, $gal) {
|
||||
%fiancé{$gal} = $guy;
|
||||
%fiancée{$guy} = $gal;
|
||||
}
|
||||
|
||||
sub perturb'em { #'
|
||||
say 'Perturb:';
|
||||
say "\tengage abi with fred and bea with jon";
|
||||
engage('fred', 'abi');
|
||||
engage('jon', 'bea');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue