-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsecret-santa.js
78 lines (64 loc) · 1.75 KB
/
secret-santa.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
class SecretSanta {
/**
* Creates an instance of SecretSanta.
* @param {Array} array - array of people [{ name, phone },...]
* @memberof SecretSanta
*/
constructor(array) {
this.array = array;
}
/**
* The Fisher-Yates (aka Knuth) shuffle algorithm
* http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
* inspired by Daplie/knuth-shuffle
*
* @param {Array} array - array to randomize
* @returns {Array} array randomized
* @memberof SecretSanta
*/
knuth (array) {
let index = array.length;
// While there remain elements to shuffle...
while (0 !== index) {
// Pick a remaining element...
const randomIndex = Math.floor(Math.random() * index);
index -= 1;
// Swap it with the current element.
[array[index], array[randomIndex]] = [array[randomIndex], array[index]]
}
return array;
}
/**
* Validate permutation of randomized array
*
* @param {Array} a - reference array
* @param {Array} b - randomized array
* @param {string} key - comparison key (f.ex `name`)
* @returns {boolean}
* @memberof SecretSanta
*/
validate (a, b, key) {
return !a.find((item, i) => item[key] === b[i][key]);
}
/**
* Build randomized assigned people array
*
* @returns {Array}
* @memberof SecretSanta
*/
build () {
let randomized = this.knuth([...this.array]);
while (!this.validate(this.array, randomized, 'name')) {
randomized = this.knuth([...this.array])
}
const validated = this.array.map((person, i) => {
return {
from: person.name,
phone: person.phone,
to: randomized[i].name,
};
});
return validated;
}
}
module.exports = SecretSanta;