Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Korko
SecretSanta.fr
Commits
f3ebd0af
Commit
f3ebd0af
authored
Dec 20, 2016
by
Korko
Browse files
Don't compute all the possibilities just to get a random one, just fetch the first that's ok
parent
47010f87
Changes
4
Hide whitespace changes
Inline
Side-by-side
app/Http/Controllers/RandomFormController.php
View file @
f3ebd0af
...
...
@@ -4,7 +4,7 @@ namespace Korko\SecretSanta\Http\Controllers;
use
Illuminate\Http\Request
;
use
Korko\SecretSanta\Http\Requests\RandomFormRequest
;
use
Korko\SecretSanta\Libs\R
andomiz
er
;
use
Korko\SecretSanta\Libs\R
esolv
er
;
use
Mail
;
use
Sms
;
use
Statsd
;
...
...
@@ -20,7 +20,7 @@ class RandomFormController extends Controller
{
$participants
=
$this
->
getParticipants
(
$request
);
$hat
=
R
andomizer
::
randomiz
e
(
$participants
);
$hat
=
R
esolver
::
resolv
e
(
$participants
);
$this
->
sendMessages
(
$request
,
$participants
,
$hat
);
...
...
app/Libs/Combinator.php
View file @
f3ebd0af
...
...
@@ -12,6 +12,8 @@ class Combinator
$combinations
=
[];
foreach
(
self
::
getGenerator
(
$elements
)
as
$combination
)
{
$combination
=
array_combine
(
$elements
,
$combination
);
if
(
isset
(
$validator
)
&&
!
self
::
isCombinationValid
(
$combination
,
$validator
))
{
continue
;
}
...
...
@@ -22,17 +24,33 @@ class Combinator
return
$combinations
;
}
public
static
function
getGenerator
(
array
$elements
)
:
Traversable
// With php7.1, return should be "?array" to return null in case of error
public
static
function
one
(
array
$elements
,
Closure
$validator
=
null
)
:
array
{
if
(
$elements
===
[])
{
yield
;
}
$rndElements
=
$elements
;
shuffle
(
$rndElements
);
foreach
(
self
::
getGenerator_internal
(
$rndElements
)
as
$combination
)
{
yield
array_combine
(
$elements
,
$combination
);
foreach
(
self
::
getGenerator
(
$rndElements
)
as
$combination
)
{
$combination
=
array_combine
(
$elements
,
$combination
);
if
(
isset
(
$validator
)
&&
!
self
::
isCombinationValid
(
$combination
,
$validator
))
{
continue
;
}
return
$combination
;
}
return
[];
}
protected
static
function
getGenerator
(
array
$elements
)
:
Traversable
{
if
(
$elements
===
[])
{
return
;
}
foreach
(
self
::
getGenerator_internal
(
$elements
)
as
$combination
)
{
yield
$combination
;
}
}
...
...
app/Libs/R
andomiz
er.php
→
app/Libs/R
esolv
er.php
View file @
f3ebd0af
...
...
@@ -4,21 +4,18 @@ namespace Korko\SecretSanta\Libs;
use
Exception
;
class
R
andomiz
er
class
R
esolv
er
{
public
static
function
r
andomiz
e
(
array
$participants
)
:
array
public
static
function
r
esolv
e
(
array
$participants
)
:
array
{
$combination
s
=
Combinator
::
all
(
array_keys
(
$participants
),
function
(
$santa
,
$target
)
use
(
$participants
)
{
$combination
=
Combinator
::
one
(
array_keys
(
$participants
),
function
(
$santa
,
$target
)
use
(
$participants
)
{
return
$santa
!==
$target
&&
!
in_array
(
$target
,
$participants
[
$santa
][
'exclusions'
]);
});
if
(
$combination
s
===
[])
{
if
(
$combination
===
[])
{
throw
new
Exception
(
'Cannot resolve '
.
json_encode
(
$participants
));
}
$rnd
=
array_rand
(
$combinations
);
$combination
=
$combinations
[
$rnd
];
foreach
(
$combination
as
$idx
=>
$idx2
)
{
$combination
[
$idx
]
=
$participants
[
$idx2
][
'name'
];
}
...
...
tests/R
andomiz
erTest.php
→
tests/R
esolv
erTest.php
View file @
f3ebd0af
<?php
use
Korko\SecretSanta\Libs\R
andomiz
er
;
use
Korko\SecretSanta\Libs\R
esolv
er
;
class
R
andomiz
erTest
extends
TestCase
class
R
esolv
erTest
extends
TestCase
{
public
function
testDuoR
andomiz
e
()
public
function
testDuoR
esolv
e
()
{
$this
->
assertEquals
([
0
=>
'B'
,
1
=>
'A'
],
R
andomizer
::
randomiz
e
([
$this
->
assertEquals
([
0
=>
'B'
,
1
=>
'A'
],
R
esolver
::
resolv
e
([
0
=>
[
'name'
=>
'A'
,
'exclusions'
=>
[]],
1
=>
[
'name'
=>
'B'
,
'exclusions'
=>
[]],
]));
$this
->
assertEquals
([
0
=>
'A'
,
1
=>
'B'
],
R
andomizer
::
randomiz
e
([
$this
->
assertEquals
([
0
=>
'A'
,
1
=>
'B'
],
R
esolver
::
resolv
e
([
0
=>
[
'name'
=>
'B'
,
'exclusions'
=>
[]],
1
=>
[
'name'
=>
'A'
,
'exclusions'
=>
[]],
]));
}
public
function
testTrioR
andomiz
e
()
public
function
testTrioR
esolv
e
()
{
$this
->
assertEquals
([
0
=>
'B'
,
1
=>
'C'
,
2
=>
'A'
],
R
andomizer
::
randomiz
e
([
$this
->
assertEquals
([
0
=>
'B'
,
1
=>
'C'
,
2
=>
'A'
],
R
esolver
::
resolv
e
([
0
=>
[
'name'
=>
'A'
,
'exclusions'
=>
[]],
1
=>
[
'name'
=>
'B'
,
'exclusions'
=>
[
'0'
]],
2
=>
[
'name'
=>
'C'
,
'exclusions'
=>
[
'1'
]],
]));
$this
->
assertEquals
([
0
=>
'C'
,
1
=>
'A'
,
2
=>
'B'
],
R
andomizer
::
randomiz
e
([
$this
->
assertEquals
([
0
=>
'C'
,
1
=>
'A'
,
2
=>
'B'
],
R
esolver
::
resolv
e
([
0
=>
[
'name'
=>
'A'
,
'exclusions'
=>
[
'1'
]],
1
=>
[
'name'
=>
'B'
,
'exclusions'
=>
[
'2'
]],
2
=>
[
'name'
=>
'C'
,
'exclusions'
=>
[]],
...
...
@@ -36,9 +36,9 @@ class RandomizerTest extends TestCase
* @expectedException Exception
* @expectedExceptionMessageRegExp #^Cannot resolve#
*/
public
function
testFailR
andomiz
e
()
public
function
testFailR
esolv
e
()
{
R
andomizer
::
randomiz
e
([
R
esolver
::
resolv
e
([
0
=>
[
'name'
=>
'A'
,
'exclusions'
=>
[
'1'
,
'2'
]],
1
=>
[
'name'
=>
'B'
,
'exclusions'
=>
[]],
2
=>
[
'name'
=>
'C'
,
'exclusions'
=>
[]],
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment