|
|
@@ -11,6 +11,7 @@ class SecretRandomizer
|
|
|
|
|
|
public function __construct($campain, $users, $constraints)
|
|
|
{
|
|
|
+ mt_srand();
|
|
|
$this->campain = $campain;
|
|
|
$this->users = $users;
|
|
|
$this->constraints = $constraints;
|
|
|
@@ -24,9 +25,45 @@ class SecretRandomizer
|
|
|
return ($this->result = $this->_getResult());
|
|
|
}
|
|
|
|
|
|
+ private static function count_candidates($candidates, $used)
|
|
|
+ {
|
|
|
+ $result = 0;
|
|
|
+ foreach ($candidates as $i)
|
|
|
+ if (!in_array($i, $used))
|
|
|
+ $result++;
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getNextPresent($candidates, $used = array())
|
|
|
+ {
|
|
|
+ if (count($candidates) == count($used))
|
|
|
+ {
|
|
|
+ $lastUser = $used[count($used) -1];
|
|
|
+ return in_array($used[0], $candidates[$lastUser]) ? $used : null;
|
|
|
+ }
|
|
|
+ $start = $i = mt_rand(0, count($candidates) - count($used) -1);
|
|
|
+ do
|
|
|
+ {
|
|
|
+ if (!in_array(array_keys($candidates)[$i], $used) &&
|
|
|
+ (!count($used) || in_array($used[count($used)-1], $candidates[array_keys($candidates)[$i]])))
|
|
|
+ if (self::count_candidates($candidates[array_keys($candidates)[$i]], $used) > 0 ||
|
|
|
+ count($candidates) == count($used) +1)
|
|
|
+ {
|
|
|
+ $used[] = array_keys($candidates)[$i];
|
|
|
+ $r = $this->getNextPresent($candidates, $used);
|
|
|
+ if ($r != null)
|
|
|
+ return $r;
|
|
|
+ array_pop($used);
|
|
|
+ }
|
|
|
+ if (--$i < 0)
|
|
|
+ $i = count($candidates) -1;
|
|
|
+ }
|
|
|
+ while ($i != $start);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
private function _getResult()
|
|
|
{
|
|
|
- $r = new SecretResult();
|
|
|
$candidates = array();
|
|
|
$allUsers = array();
|
|
|
foreach ($this->users as $i)
|
|
|
@@ -41,7 +78,7 @@ class SecretRandomizer
|
|
|
unset($candidates[$i->getUserA()][array_search($i->getUserB(), $candidates[$i->getUserA()])]);
|
|
|
unset($candidates[$i->getUserB()][array_search($i->getUserA(), $candidates[$i->getUserB()])]);
|
|
|
}
|
|
|
- return $r;
|
|
|
+ return new SecretResult($this->getNextPresent($candidates));
|
|
|
}
|
|
|
}
|
|
|
|