Stable marriage problem: Difference between revisions

Content added Content deleted
(→‎{{header|Python}}: Remove more debugging/setup code)
(→‎Tcl: Added implementation)
Line 335: Line 335:
fay likes jon better than dan and jon likes fay better than their current partner
fay likes jon better than dan and jon likes fay better than their current partner
Engagement stability check FAILED</pre>
Engagement stability check FAILED</pre>

=={{header|Tcl}}==
{{trans|Python}}
<lang tcl>package require Tcl 8.5

# Functions as aliases to standard commands
interp alias {} tcl::mathfunc::pos {} ::lsearch -exact
interp alias {} tcl::mathfunc::nonempty {} ::llength

# The stability check
proc check engaged {
global preferences
set inverse [lreverse $engaged]
dict for {she he} $engaged {
set shelikes [dict get $preferences $she]
set shelikesbetter [lrange $shelikes 0 [expr {pos($shelikes,$he)}]]
set helikes [dict get $preferences $he]
set helikesbetter [lrange $helikes 0 [expr {pos($helikes,$she)}]]
foreach guy $shelikesbetter {
set guysgirl [dict get $inverse $guy]
set guylikes [dict get $preferences $guy]
if {pos($guylikes,$guysgirl) > pos($guylikes,$she)} {
puts "$she likes $guy better than $he and $he likes $she better than their current partner"
return 0
}
}
foreach gal $helikesbetter {
set galsguy [dict get $engaged $gal]
set gallikes [dict get $preferences $gal]
if {pos($gallikes,$galsguy) > pos($gallikes,$he)} {
puts "$he likes $gal better than $she and $she likes $he better than their current partner"
return 0
}
}
}
return 1
}

# The match-making algorithm
proc matchmaker {} {
global guys gals preferences
set guysfree $guys
set engaged {}
array set p $preferences
while {nonempty($guysfree)} {
set guysfree [lassign $guysfree guy]
set p($guy) [set guyslist [lassign $p($guy) gal]]
if {![dict exists $engaged $gal]} {
# She's free
dict set engaged $gal $guy
puts " $guy and $gal"
continue
}
# The bounder proposes to an engaged lass!
set fiance [dict get $engaged $gal]
if {pos($p($gal), $fiance) > pos($p($gal), $guy)} {
# She prefers the new guy
dict set engaged $gal $guy
puts " $gal dumped $fiance for $guy"
set guy $fiance
}
if {nonempty($p($guy))} {
lappend guysfree $guy
}
}
return $engaged
}

# Problem dataset
set guys {abe bob col dan ed fred gav hal ian jon}
set gals {abi bea cath dee eve fay gay hope ivy jan}
set preferences {
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}
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}
}

# The demonstration code
puts "Engagements:"
set engaged [matchmaker]

puts "\nCouples:"
set pfx ""
foreach gal $gals {
puts -nonewline "$pfx $gal is engaged to [dict get $engaged $gal]"
set pfx ",\n"
}
puts "\n"
puts "Engagement stability check [lindex {FAILED PASSED} [check $engaged]]"

puts "\n\nSwapping two fiances to introduce an error"
set tmp [dict get $engaged [lindex $gals 0]]
dict set engaged [lindex $gals 0] [dict get $engaged [lindex $gals 1]]
dict set engaged [lindex $gals 1] $tmp
foreach gal [lrange $gals 0 1] {
puts " $gal is now engaged to [dict get $engaged $gal]"
}
puts ""
puts "Engagement stability check [lindex {FAILED PASSED} [check $engaged]]"</lang>
Sample output:
<pre>
Engagements:
abe and abi
bob and cath
col and hope
dan and ivy
ed and jan
fred and bea
gav and gay
hope dumped col for ian
abi dumped abe for jon
hal and eve
col and dee
ivy dumped dan for abe
dan and fay

Couples:
abi is engaged to jon,
bea is engaged to fred,
cath is engaged to bob,
dee is engaged to col,
eve is engaged to hal,
fay is engaged to dan,
gay is engaged to gav,
hope is engaged to ian,
ivy is engaged to abe,
jan is engaged to ed

Engagement stability check PASSED


Swapping two fiances to introduce an error
abi is now engaged to fred
bea is now engaged to jon

fred likes bea better than abi and abi likes fred better than their current partner
Engagement stability check FAILED
</pre>