-
Notifications
You must be signed in to change notification settings - Fork 0
/
create_pairs.js
78 lines (62 loc) · 2.27 KB
/
create_pairs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
module.exports = {
createPairs,
isValidPair,
checkPairsAreValid,
};
function createPairs(participants, disallowedPairs) {
const pairs = [];
// clone participants into new array
let receivers = participants.map(x => x);
participants.forEach(participant => {
const possibleReceivers = receivers.filter(receiver => isValidPair(participant, receiver, disallowedPairs));
// repeat the method if there aren't any valid pairs left
if (possibleReceivers.length < 1) return createPairs(participants);
const receiver = possibleReceivers[Math.floor(Math.random() * possibleReceivers.length)];
pairs.push([participant, receiver]);
receivers = receivers.filter(elem => elem !== receiver);
});
if (receivers.length > 0 || !checkPairsAreValid(participants, pairs, disallowedPairs)) throw 'What? qwer';
return pairs;
}
function isValidPair(user1, user2, disallowedPairs) {
let error = false;
if (user1 === user2) return false;
disallowedPairs.forEach(disallowedPair => {
if (disallowedPair.includes(user1) && disallowedPair.includes(user2)) {
error = true;
return false;
}
});
if (error) return false;
return true;
}
// Just to make sure everyone is included
function checkPairsAreValid(participants, pairs, disallowedPairs) {
let error = false;
if (participants.length !== pairs.length) return;
const list1 = pairs.map(pair => pair[0]);
const list2 = pairs.map(pair => pair[1]);
participants.forEach(participant => {
// check if user receives and gives exactly one present
if (list1.filter(user => user === participant).length !== 1 || list2.filter(user => user === participant).length !== 1) {
error = true;
return false;
}
});
if (error) return false;
pairs.forEach((pair) => {
if (pair[0] === pair[1]) {
error = true;
return false;
}
disallowedPairs.forEach(disallowedPair => {
if (disallowedPair.includes(pair[0]) && disallowedPair.includes(pair[1])) {
error = true;
return false;
}
});
if (error) return false;
});
if (error) return false;
return true;
}