UNPKG

eventassigner-js

Version:

A NPM package to assign groups / persons to events based on their preference

193 lines (167 loc) 6.93 kB
'use strict'; var _countPlayersInEvent = require('./countPlayersInEvent'); var _updateGroupsAfterAssignment = require('./updateGroupsAfterAssignment'); /* eslint-disable import/named */ function padgOpt(input) { var groups = input.groups, events = input.events, list = input.list, updateL = input.updateL; var assignment = groups.map(function (group) { var returnObject = {}; returnObject.id = group.id; returnObject.assignment = -1; return returnObject; }); var phantomEvents = []; // Phantom events // function definitions for PhantomEvents phantomEvents.createEntry = function (newEntry) { // function to create a new entry to S phantomEvents.push({ id: newEntry.id, min: newEntry.min, max: newEntry.max }); }; phantomEvents.removeEntry = function (eventid) { var ind = phantomEvents.findIndex(function (ele) { return ele.id === eventid; }); phantomEvents.splice(ind, 1); }; phantomEvents.includesEvent = function (event) { // check if event named eventName is in P if (phantomEvents.filter(function (e) { return e.id === event.id; }).length === 1) { return 1; } else { return 0; } }; // define deficit var deficit = 0; // initialize V to be the same as groups var unassignedGroups = groups.slice(); unassignedGroups.countPlayers = function () { return unassignedGroups.reduce(function (total, group) { return total + group.size; }, 0); }; unassignedGroups.removeGroup = function (groupId) { var returnArray = unassignedGroups.filter(function (group) { return group.id !== groupId; }); returnArray.countPlayers = function () { return returnArray.reduce(function (total, group) { return total + group.size; }, 0); }; return returnArray; }; // MAIN LOOP STARTS HERE list = list.filter(function (ele) { return ele.gain > 0; }); var _loop = function _loop() { var listElement = list.pop(); var eventInd = events.findIndex(function (e) { return e.id === listElement.event; }); var groupInd = groups.findIndex(function (g) { return g.id === listElement.id; }); var assignmentInd = assignment.findIndex(function (a) { return a.id === listElement.id; }); /* listElement is the last index of LL check if there are enough people signed up for this game in order to avoid matching some group with this event without hope of this event ever happening */ var numPlayersToThisEvent = groups.reduce(function (total, group) { if (typeof group.pref.find(function (p) { return p === listElement.event; }) !== 'undefined') { return total + group.size; } else { return total; } }, 0); if (listElement.gain === 0 || numPlayersToThisEvent < events[eventInd].min) { // consider only cases where adding u to event increases happiness // and those where there is even theoretically possible to have // minimum number of players // eslint-disable-next-line no-continue return 'continue'; } if (assignment[assignmentInd].assignment === -1 && (0, _countPlayersInEvent.countPlayersInEvent)(groups, events, listElement.event) + listElement.size <= events[eventInd].max) { // group in listElement is not assigned and there is space in the event where we try to place // const playersBefore = if ((0, _countPlayersInEvent.countPlayersInEvent)(groups, events, listElement.event) === 0) { // no players in this event if (deficit + (events[eventInd].min - listElement.size) < unassignedGroups.countPlayers()) { // adding listElement to this event does not decrease deficit over critical size // since event is not yet real event add it to P // add to deficit how much space was left over in this event and update deficit deficit += events[eventInd].min - listElement.size; if (phantomEvents.includesEvent(events[eventInd]) === 0) { var newPEntry = { id: events[eventInd].id, min: events[eventInd].min, max: events[eventInd].max }; phantomEvents.createEntry(newPEntry); } } else { // eslint-disable-next-line no-continue return 'continue'; } } else if (phantomEvents.includesEvent(events[eventInd]) === 1) { // event has players, decrease deficit deficit -= listElement.size; } events[eventInd].groups.push(listElement.id); unassignedGroups.removeGroup(listElement.id); if ((0, _countPlayersInEvent.countPlayersInEvent)(groups, events, listElement.event) >= events[eventInd].min && phantomEvents.includesEvent(events[eventInd]) === 0) { // this event is not a phantom event, set M(u) to a assignment[assignmentInd].assignment = listElement.event; var updatedObjects = (0, _updateGroupsAfterAssignment.updateGroupsAfterAssignment)(events, phantomEvents, groups, unassignedGroups, assignment, groups[groupInd], listElement.event, 'real'); groups = updatedObjects.returnGroups; events = updatedObjects.returnEvents; deficit = updatedObjects.returnDeficit; unassignedGroups = updatedObjects.returnUnassignedGroups; phantomEvents = updatedObjects.returnPhantomEvents; assignment = updatedObjects.returnAssignment; } if ((0, _countPlayersInEvent.countPlayersInEvent)(groups, events, listElement.event) >= events[eventInd].min && phantomEvents.includesEvent(events[eventInd]) === 1) { // this event is a phantom event but has now enough players to be a real event assignment[assignmentInd].assignment = listElement.event; var _updatedObjects = (0, _updateGroupsAfterAssignment.updateGroupsAfterAssignment)(events, phantomEvents, groups, unassignedGroups, assignment, groups[groupInd], listElement.event, 'phantomToReal'); groups = _updatedObjects.returnGroups; events = _updatedObjects.returnEvents; deficit = _updatedObjects.returnDeficit; unassignedGroups = _updatedObjects.returnUnassignedGroups; phantomEvents = _updatedObjects.returnPhantomEvents; assignment = _updatedObjects.returnAssignment; } // Update list LL if there was no assignment if (assignment[assignmentInd].assignment === -1) { list = updateL({ groups: groups, events: events, assignment: assignment, unassignedGroups: unassignedGroups, deficit: deficit, list: list, groupId: listElement.id }); } } }; while (list.length > 0) { var _ret = _loop(); if (_ret === 'continue') continue; } return assignment; } module.exports = { padgOpt: padgOpt };