From eaaed0356687533d919f271e339386cbfd5bc282 Mon Sep 17 00:00:00 2001 From: Michal Hanajik Date: Wed, 3 Oct 2018 15:12:33 +0100 Subject: [PATCH 1/5] Implementation Stable marriage problem in PHP --- .../code/php/stable_marriage.php | 140 ++++++++++++++++++ .../stable_marriage_problem.md | 2 + 2 files changed, 142 insertions(+) create mode 100644 contents/stable_marriage_problem/code/php/stable_marriage.php diff --git a/contents/stable_marriage_problem/code/php/stable_marriage.php b/contents/stable_marriage_problem/code/php/stable_marriage.php new file mode 100644 index 000000000..d2a09f04d --- /dev/null +++ b/contents/stable_marriage_problem/code/php/stable_marriage.php @@ -0,0 +1,140 @@ +name = $name; } + + public function getName(): string + { + return $this->name; + } + + public function setPreferences(array $preferences): void + { + shuffle($preferences); + $this->preferences = $preferences; + } + + public function getMatch(): Person + { + return $this->match; + } + + public function getPreferences(): array + { + return $this->preferences; + } + + public function isSingle(): bool + { + return $this->match === null; + } + + public function unmatch(): void + { + $this->match = null; + } + + public function setMatch(Person $match): void + { + if ($this->match !== $match) { + if ($this->match !== null) { + $this->match->unmatch(); + } + $this->match = $match; + if ($match !== null) $match->setMatch($this); + } + } + + public function __toString(): string + { + return $this->name; + } +} + +class Man extends Person +{ + public function propose(): void + { + if (!empty($this->preferences)) { + /** @var Woman $fiance */ + $fiance = array_shift($this->preferences); + $fiance->receiveProposal($this); + } + } +} + +class Woman extends Person +{ + /** @var Man[] */ + private $suitors = []; + + public function receiveProposal(Man $man): void + { + $this->suitors[] = $man; + } + + public function chooseMatch(): void + { + foreach ($this->preferences as $preference) { + if ($preference === $this->match || in_array($preference, $this->suitors)) { + $this->setMatch($preference); + break; + } + } + } +} + +function stable_marriage(array $men, array $women): void +{ + $smallerGroup = count($men) < count($women) ? $men : $women; + /** @var Woman $woman */ + /** @var Man $man */ + do { + foreach ($men as $man) + if ($man->isSingle()) $man->propose(); + + foreach ($women as $woman) + $woman->chooseMatch(); + + /** @var Person $person */ + if (empty(array_filter($smallerGroup, function (Person $person) { + return $person->isSingle(); + }))) break; + + } while (true); + + foreach ($women as $woman) echo sprintf('%s is married to %s%s', $woman, $woman->getMatch(), PHP_EOL); +} + +$groupSize = 10; +$men = []; +$women = []; + +for ($i = 1; $i <= $groupSize; $i++) { + $men[] = new Man("M${i}"); + $women[] = new Woman("W${i}"); +} + +/** @var Man $man */ +/** @var Woman $woman */ +foreach ($men as $man) { + $man->setPreferences($women); + echo sprintf('%s\'s choices:%s', $man->getName(), PHP_EOL); + echo sprintf('%s%s', implode(',', $man->getPreferences()), PHP_EOL); +} +echo PHP_EOL; +foreach ($women as $woman) { + $woman->setPreferences($men); + echo sprintf('%s\'s choices:%s', $woman->getName(), PHP_EOL); + echo sprintf('%s%s', implode(',', $woman->getPreferences()), PHP_EOL); +} +echo PHP_EOL; +stable_marriage($men, $women); diff --git a/contents/stable_marriage_problem/stable_marriage_problem.md b/contents/stable_marriage_problem/stable_marriage_problem.md index c1d12d674..9694b9f8c 100644 --- a/contents/stable_marriage_problem/stable_marriage_problem.md +++ b/contents/stable_marriage_problem/stable_marriage_problem.md @@ -44,6 +44,8 @@ I am incredibly interested to see what you guys do and how you implement the alg [import, lang:"csharp"](code/csharp/ListExtensions.cs) {% sample lang="java" %} [import, lang:"java"](code/java/stable-marriage.java) +{% sample lang="php" %} +[import, lang:"php"](code/php/stable_marriage.php) {% endmethod %}