Stable marriage problem: Difference between revisions
m
syntax highlighting fixup automation
Alextretyak (talk | contribs) (Added 11l) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 56:
{{trans|Python}}
<
‘bob’ = [‘cath’, ‘hope’, ‘abi’, ‘dee’, ‘eve’, ‘fay’, ‘bea’, ‘jan’, ‘ivy’, ‘gay’],
‘col’ = [‘hope’, ‘eve’, ‘abi’, ‘dee’, ‘bea’, ‘fay’, ‘ivy’, ‘gay’, ‘cath’, ‘jan’],
Line 139:
print(‘ #. is now engaged to #.’.format(gal, engaged[gal]))
print()
print(I check(engaged) {‘Engagement stability check PASSED’} E ‘Engagement stability check FAILED’)</
{{out}}
Line 184:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey L}}
<
abe := ["abi", "eve", "cath", "ivy", "jan", "dee", "fay", "bea", "hope", "gay"]
bob := ["cath", "hope", "abi", "dee", "eve", "fay", "bea", "jan", "ivy", "gay"]
Line 272:
Else
Return "`nThese couples are stable.`n"
}</
{{out}}
<pre>Engagements:
Line 328:
=={{header|Batch File}}==
<
:: Batch File Implementation
Line 475:
set "!%~1.tmp!_=%~2"
set "!%~2.tmp!_=%~1"
goto :EOF</
{{Out}}
<pre>HISTORY:
Line 528:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
DIM mname$(N), wname$(N), mpref$(N), wpref$(N), mpartner%(N), wpartner%(N)
DIM proposed&(N,N)
Line 595:
NEXT o%
NEXT m%
= TRUE</
'''Output:'''
<pre>
Line 617:
=={{header|Bracmat}}==
<
(bob.cath hope abi dee eve fay bea jan ivy gay)
(col.hope eve abi dee bea fay ivy gay cath jan)
Line 682:
| out$stable
)
);</
{{out}}
<pre>stable
Line 700:
=={{header|C}}==
Oddly enough (or maybe it should be that way, only that I don't know): if the women were proposing instead of the men, the resulting pairs are exactly the same.
<
int verbose = 0;
Line 833:
return 0;
}</
{{out}}
<pre>Pairing:
Line 859:
=={{header|C sharp|C#}}==
(This is a straight-up translation of the Objective-C version.)
<
using System.Collections.Generic;
Line 983:
}
}
}</
{{out}}
Line 1,002:
=={{header|C++}}==
<
#include <iostream>
#include <map>
Line 1,142:
check_stability(engaged, men_pref, women_pref);
}</
{{out}}
<pre>
Line 1,182:
=={{header|Ceylon}}==
<
shared String name;
Line 1,319:
}
print("``if(!stabilityFlag) then "Not " else ""``Stable!");
}</
{{out}}
<pre>------ the matchmaking process ------
Line 1,360:
=={{header|CoffeeScript}}==
<
constructor: (@name, @preferences) ->
@mate = null
Line 1,487:
perturb guys
report_on_mates guys
report_potential_adulteries guys</
{{out}}
<pre>
Line 1,543:
=={{header|ColdFusion}}==
<
PERSON.CFC
Line 1,665:
}
}
</syntaxhighlight>
<
INDEX.CFM
Line 1,780:
}
</cfscript>
</syntaxhighlight>
{{out}}
<pre>
Line 1,850:
=={{header|D}}==
From the Python and Java versions:
<
Line 1,979:
c = check!(true)(engagedTo, guyPrefers, galPrefers);
writeln("Marriages are ", c ? "stable" : "unstable");
}</
{{out}}
<pre>Engagements:
Line 2,005:
Marriages are unstable</pre>
===Stronger Version===
<
enum F { abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan }
Line 2,124:
checkStability(engaged, menPref, womenPref);
}
</syntaxhighlight>
{{out}}
<pre>Matchmaking:
Line 2,162:
=={{header|EchoLisp}}==
<
(lib 'hash)
;; input data
Line 2,237:
(error 'not-stable (list man woman)))))
</syntaxhighlight>
{{out}}
<pre>
Line 2,274:
=={{header|F_Sharp|F#}}==
<
Map.ofList
["abe", ["abi";"eve";"cath";"ivy";"jan";"dee";"fay";"bea";"hope";"gay"];
Line 2,420:
husbandOf = solution.husbandOf.Add( gal0, guy1 ).Add( gal1, guy0 ) }
printfn "Perturbed is stable: %A" (isStable perturbed)</
{{out}}
<pre>
Line 2,438:
=={{header|Go}}==
<
import "fmt"
Line 2,641:
fmt.Println("stable.")
return true
}</
{{out}}
<pre>
Line 2,695:
"Stable Matching" Solution:
<
import static Woman.*
Line 2,720:
}
engagedTo
}</
"Stability Checking" Solution:
(Could do more to eliminate common code. Maybe later.)
<
matches.collect{ girl, guy ->
int guysRank = galsGuyRanking[girl][guy]
Line 2,749:
true
}.every()
}</
Test (Stable and Perturbed):
<
abe, bob, col, dan, ed, fred, gav, hal, ian, jon
}
Line 2,807:
println ''
assert ! isStable(matches, mansWomanRanking, womansManRanking)</
{{out}}
<pre>abi (his '10' girl) is engaged to jon (her '8' guy)
Line 2,852:
The state here consists of the list of free guys and associative preferences lists for guys and girls correspondingly. In order to simplify the access to elements of the state we use lenses.
<
import Lens.Micro
import Lens.Micro.TH
Line 2,863:
, _girls :: [Preferences a]}
makeLenses ''State</
Lenses allow us to get access to each person in the state, and even to the associated preference list:
<
where get = head . dropWhile ((/= n).fst)
set assoc (_,v) = let (prev, _:post) = break ((== n).fst) assoc
Line 2,873:
fianceesOf n = guys.name n._2
fiancesOf n = girls.name n._2</
Note that in following we use lens operators:
Line 2,885:
With these tools and notes we are ready to implement the Gale/Shapley algorithm and the stability test as they are given in a textbook:
<
stableMatching = getPairs . until (null._freeGuys) step
where
Line 2,915:
, elemIndex w2 fm < elemIndex w1 fm
, let fw = s^.fiancesOf w2
, elemIndex m2 fw < elemIndex m1 fw ]</
This solution works not only for strings, but for any equable data.
Line 2,923:
Here are the given preferences:
<
[("abe", ["abi", "eve", "cath", "ivy", "jan", "dee", "fay", "bea", "hope", "gay"]),
("bob", ["cath", "hope", "abi", "dee", "eve", "fay", "bea", "jan", "ivy", "gay"]),
Line 2,945:
("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 initial state:
<
And the solution:
Line 2,979:
=={{header|Icon}} and {{header|Unicon}}==
<
procedure main()
Line 3,091:
return X
end</
{{libheader|Icon Programming Library}}
Line 3,143:
=={{header|J}}==
<
abe: abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay
bob: cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay
Line 3,214:
end.
assert-.bad
)</
For most of this, males and females are both represented by indices. Rows of <code>Mprefs</code> are indexed by a male index and each contains a list female indices, in priority order. Rows of <code>Fprefs</code> are indexed by a female index and each contains a list male indices in priority order. These indices select the corresponding names from <code>GuyNames</code> and <code>GalNames</code>.
Line 3,222:
Example use:
<
┌───┬────┬───┬───┬───┬────┬───┬───┬────┬───┐
│abe│bob │col│dan│ed │fred│gav│hal│ian │jon│
├───┼────┼───┼───┼───┼────┼───┼───┼────┼───┤
│ivy│cath│dee│fay│jan│bea │gay│eve│hope│abi│
└───┴────┴───┴───┴───┴────┴───┴───┴────┴───┘</
Stability check:
<
</
(no news is good news)
Line 3,238:
An altered result, and a stability check on it (showing what would happen for a bogus result):
<
┌───┬────┬───┬───┬───┬────┬───┬───┬────┬───┐
│abe│bob │col│dan│ed │fred│gav│hal│ian │jon│
Line 3,256:
└────┴───┘
|assertion failure: assert
| assert-.bad</
As an aside, note that the guys fared much better than the gals here, with over half of the guys getting their first preference and only one gal getting her first preference. The worst match for any guy was fourth preference where the worst for any gal was seventh preference.
=={{header|Java}}==
This is not a direct translation of [[#Python|Python]], but it's fairly close (especially the stability check).
<
public class Stable {
Line 3,440:
return true;
}
}</
{{out}}
<pre>abi is engaged to jon
Line 3,458:
=={{header|JavaScript}}==
<
var candidateIndex = 0;
Line 3,579:
doMarriage();
</syntaxhighlight>
{{out}}
Line 3,597:
=={{header|Julia}}==
<syntaxhighlight lang="julia">
# This is not optimized, but tries to follow the pseudocode given the Wikipedia entry below.
# Reference: https://en.wikipedia.org/wiki/Stable_marriage_problem#Algorithm
Line 3,724:
tableprint("Original Data With Bob and Abe Switched", answer[1], stabl)
</syntaxhighlight>
{{out}}
<pre>
Line 3,784:
=={{header|Kotlin}}==
<
data class Person(val name: String) {
val preferences = mutableListOf<Person>()
Line 3,891:
println("#### match is stable: ${isStableMatch(males, females)}")
}
</syntaxhighlight>
{{out}}
<pre>
Line 3,922:
{{trans|C#}}
<
Person.__index = Person
Line 4,050:
jon.fiance, fred.fiance = fred.fiance, jon.fiance
print('Stable: ', isStable(men))
</syntaxhighlight>
{{out}}
Line 4,074:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
ClearAll[CheckStability]
CheckStabilityHelp[male_, female_, ml_List, fl_List, pairing_List] := Module[{prefs, currentmale},
Line 4,125:
pairing[[{2, 7}, 2]] //= Reverse;
pairing
CheckStability[ml, fl, pairing]</
{{out}}
<pre>{{1,9},{2,3},{3,4},{4,6},{5,10},{6,2},{7,7},{8,5},{9,8},{10,1}}
Line 4,133:
=={{header|Nim}}==
<
const
Line 4,250:
echo "Current pair analysis:"
discard checkPairStability(contPairs, recPairs)
</syntaxhighlight>
{{out}}
<pre>abe 💑 ivy
Line 4,283:
{{Works with|XCode 4.5.1}}
(The C# version is essentially the same as this.)
<
// Person class
Line 4,419:
}
return 0;
}</
{{out}}
Line 4,438:
=={{header|OCaml}}==
<
"abe", ["abi";"eve";"cath";"ivy";"jan";"dee";"fay";"bea";"hope";"gay"];
"bob", ["cath";"hope";"abi";"dee";"eve";"fay";"bea";"jan";"ivy";"gay"];
Line 4,595:
let engagements = perturb_engagements engagements in
print engagements;
;;</
{{out}}
<pre> fay is engaged with dan
Line 4,622:
=={{header|Perl}}==
<
use strict;
use warnings;
Line 4,738:
sub men { keys %{ $Likes{M} } }
sub women { keys %{ $Likes{W} } }</
{{out}}
<pre>
Line 4,769:
=={{header|Phix}}==
{{trans|AutoHotkey}}
<!--<
<span style="color: #008080;">constant</span> <span style="color: #000000;">men</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"abe"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bob"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"col"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"dan"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ed"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"fred"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"gav"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"hal"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ian"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"jon"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">abe</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">bob</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">col</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">dan</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">ed</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">fred</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">gav</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">hal</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">ian</span> <span style="color: #0000FF;">,</span> <span style="color: #000000;">jon</span>
Line 4,857:
<span style="color: #000000;">engagements</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cath</span><span style="color: #0000FF;">]:=</span><span style="color: #000000;">abe</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">engagements</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ivy</span><span style="color: #0000FF;">]:=</span><span style="color: #000000;">bob</span>
<span style="color: #000000;">stable</span><span style="color: #0000FF;">()</span>
<!--</
{{Out}}
<pre>
Line 4,900:
=={{header|PicoLisp}}==
<
*Boys (list
(de abe abi eve cath ivy jan dee fay bea hope gay)
Line 4,964:
(con (asoq 'fred *Couples) 'abi)
(con (asoq 'jon *Couples) 'bea)
(checkCouples)</
{{out}}
<pre>dee is engaged to col
Line 4,987:
{{Works with|SWI-Prolog}}{{libheader|XPCE}}
XPCE is used for its integrated messaging system.
<
% facts
prefere(abe,[ abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay]).
Line 5,260:
( (IY12 < IY11 , IX21 < IX22);
(IY21 < IY22 , IX12 < IX11)).
</syntaxhighlight>
{{out}}
<pre> ?- stable_mariage.
Line 5,287:
true </pre>
A more Prolog-ish version (working with SWI-Prolog) could be :
<
% person(Name, Preference, Status, Candidate)
% prop(Name, List_of_Candidates) (for a woman)
Line 5,500:
% A couple is unstable
( (IY12 < IY11 , IX21 < IX22);
(IY21 < IY22 , IX12 < IX11)).</
=={{header|PureBasic}}==
This approach uses a messaging system to pass messages between prospective partners.
<
DataSection
Line 5,677:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</
{{out}}
<pre>Marriages:
Line 5,705:
=={{header|Python}}==
<
guyprefers = {
Line 5,807:
print()
print('Engagement stability check PASSED'
if check(engaged) else 'Engagement stability check FAILED')</
{{out}}
<pre>Engagements:
Line 5,847:
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
Line 5,933:
(swap! (hash-ref matches (car M)) (hash-ref matches (cadr M))))
(check-stability)
</syntaxhighlight>
Sample run:
Line 5,957:
{{Works with|rakudo|2016.10}}
{{trans|Perl}}
<syntaxhighlight lang="raku"
abe => < abi eve cath ivy jan dee fay bea hope gay >,
bob => < cath hope abi dee eve fay bea jan ivy gay >,
Line 6,044:
engage('fred', 'abi');
engage('jon', 'bea');
}</
{{out}}
<pre>Matchmaking:
Line 6,071:
=={{header|REXX}}==
Algorithm used: see link https://www.youtube.com/watch?v=Qcv1IqHWAzg
<
* pref.b Preferences of boy b
* pref.g Preferences of girl g
Line 6,275:
s=left(s,p-1)||new||substr(s,p+length(old))
End
Return s </
{{out}}
<pre>
Line 6,301:
=={{header|Ruby}}==
<
def initialize(name)
@name = name
Line 6,471:
@men.each_value.collect {|man| puts "#{man} + #{man.fiance}"}
stability @men</
{{out}}
<pre>abe + ivy
Line 6,507:
=={{header|Scala}}==
{{trans|Java}}
<
private def checkMarriages(): Unit =
if (check)
Line 6,613:
swap()
checkMarriages()
}</
{{out}}
See Java output.
=={{header|Seed7}}==
<
const type: preferences is hash [string] array string;
Line 6,767:
writeln;
writeln("Marriages are " <& [] ("unstable", "stable") [succ(ord(check(engagedTo, guyPrefers, girlPrefers)))]);
end func;</
Output:
Line 6,809:
=={{header|Sidef}}==
{{trans|Raku}}
<
abe => < abi eve cath ivy jan dee fay bea hope gay >,
bob => < cath hope abi dee eve fay bea jan ivy gay >,
Line 6,897:
perturb_em();
check_stability();</
{{out}}
<pre>
Line 6,929:
The data set package:
<
is
Line 6,972:
end Preferences;
</syntaxhighlight>
The package for creating the engagements and checking stability. This package can be analysed by the SPARK tools and proved to be free of any run-time error.
<
--# inherit Preferences;
package Propose
Line 6,993:
end Propose;
</syntaxhighlight>
<
use type Preferences.Extended_Rank;
use type Preferences.Girl;
Line 7,132:
end Propose;
</syntaxhighlight>
The test program tests all pairwise exchanges. This is Ada, it is not SPARK.
(Text IO is quite tedious in SPARK - it's not what the language was designed for.)
<
-- Test program.
--
Line 7,202:
end MatchMaker;
</syntaxhighlight>
The begining of the output from the test. All pairwise exchanges create unstable pairings.
<pre>ABI marries JON
Line 7,228:
=={{header|Swift}}==
{{trans|JavaScript}}
<
let name:String
var candidateIndex = 0
Line 7,365:
}
doMarriage()</
{{out}}
<pre>
Line 7,384:
=={{header|Tcl}}==
{{trans|Python}}
<
# Functions as aliases to standard commands
Line 7,499:
}
puts ""
puts "Engagement stability check [lindex {FAILED PASSED} [check $engaged]]"</
{{out}}
<pre>
Line 7,543:
{{works with|Bourne Again Shell|4.0}}
{{trans|AutoHotkey}}
<
main() {
# Our ten males:
Line 7,709:
}
main "$@"</
{{Out}}
<pre>abi accepted abe
Line 7,766:
=={{header|Ursala}}==
<
{
Line 7,813:
'stable': match/men women,
'perturbed': ~&lSrSxPp match/men women,
'preferred': preferred/(men,women) ~&lSrSxPp match/men women></
The matches are perturbed by reversing the order of the women.
{{out}}
Line 7,873:
'''The string approach'''<br/>
<
c00 = "_abe abi eve cath ivy jan dee fay bea hope gay " & _
"_bob cath hope abi dee eve fay bea jan ivy gay " & _
Line 7,916:
MsgBox Replace(Join(Filter(Split(c00), "-"), vbLf), "_", "")
End Sub</
'''The Dictionary approach'''
<
Set d_00 = CreateObject("scripting.dictionary")
Set d_01 = CreateObject("scripting.dictionary")
Line 7,975:
MsgBox Join(d_00.items, vbLf)
End Sub</
{{out}}
Line 7,995:
{{libheader|Wren-dynamic}}
Although this is a faithful translation, the results are not identical to those of Go as map iteration order in both languages is undefined.
<
var mPref = {
Line 8,165:
if (!validateStable.call(ps, mPref, wPref)) return
// if those happened to be stable as well, perturb more
}</
{{out}}
Line 8,222:
Assume that the input is in XML form as listed [[Stable marriage problem/XSLT input|here]]. The following XSLT 2.0 style-sheet...
<syntaxhighlight lang="text"><xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
Line 8,357:
</xsl:function>
</xsl:stylesheet></
...when applied to the said input document will yield...
<syntaxhighlight lang="text"><t>
<m:stable-marriage-problem-result xmlns:m="http://rosettacode.org/wiki/Stable_marriage_problem">
<m:solution is-stable="true">
Line 8,408:
<m:message>The perturbed configuration is unstable.</m:message>
</m:stable-marriage-problem-result>
</t></
=={{header|zkl}}==
{{trans|PicoLisp}}
<
Boys=Dictionary(
"abe", "abi eve cath ivy jan dee fay bea hope gay".split(),
Line 8,473:
Couples.filter1("holds","fred")[1]="abi";
Couples.filter1("holds","jon") [1]="bea";
checkCouples(Couples);</
{{out}}
<pre>
|