Skip to content

Instantly share code, notes, and snippets.

@dom111
Created October 20, 2015 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dom111/4a4ede77f44c46c5d968 to your computer and use it in GitHub Desktop.
Save dom111/4a4ede77f44c46c5d968 to your computer and use it in GitHub Desktop.
function santa(data) {
// get the names from the first index of the array
var names = data.map(a => a.shift()),
result = {};
// build the data structure as an object of gifter => giftees
names.map((name, i) => result[name] = data[i].map((v, j) => v ? names[j] : false).filter(v => v));
// iterate around each name
while (names.length) {
// make sure we start with the name that has the fewest choices
var name;
names = names.sort((a, b) => result[a].length - result[b].length);
name = names.shift();
// if we don't have any names left, it must be impossible
if (result[name].length == 0) {
return false
}
else {
// pick a name at random from the list
var selectedName = result[name][Math.floor(result[name].length * Math.random())];
// and set it as the object
result[name] = selectedName;
// if it's not just a string now...
if (typeof result[selectedName] == 'object') {
// filter the current name from the list
result[selectedName] = result[selectedName].filter(value => value != name);
}
// filter all the remaining arrays to ensure we can't pick the same one again
names.map(currentName => result[currentName] = result[currentName].filter(value => value != selectedName));
}
}
return result;
}
/* usage:
santa([
["Alice", 0, 0, 1, 1, 1, 1, 1],
["Bob", 0, 0, 0, 0, 0, 1, 0],
["Carla", 1, 1, 0, 0, 0, 1, 1],
["Dan", 1, 1, 0, 0, 0, 1, 1],
["Erin", 1, 1, 0, 0, 0, 1, 1],
["Frank", 1, 1, 1, 1, 1, 0, 1],
["Gary", 1, 1, 1, 1, 1, 1, 0]
]);
// might return something like:
[
["Alice", "Dan"],
["Bob", "Erin"],
["Carla", "Bob"],
["Dan", "Alice"],
["Erin", "Frank"],
["Frank", "Carla"]
]
santa([
["Alice", 0, 1, 1, 1, 0, 1],
["Bob", 0, 0, 1, 1, 0, 1],
["Carla", 0, 1, 0, 1, 0, 1],
["Dan", 0, 1, 1, 0, 0, 0],
["Erin", 0, 0, 1, 0, 0, 1],
["Frank", 1, 1, 1, 1, 1, 0]
]);
// would always return
false
santa([
["Alice", 0, 1, 1],
["Bob", 1, 0, 1],
["Carla", 1, 1, 0]
]);
// might return something like:
[
["Alice", "Bob"],
["Bob", "Carla"],
["Carla", "Alice"]
]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment