Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -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).

View file

@ -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#)");
}
}

View file

@ -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>

View file

@ -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]);

View file

@ -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;

View file

@ -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) {

View file

@ -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');
}