Station Algorithm 1

by dzejkej

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<div id="console-log"></div>

CSS

.console-line
{
    font-family: monospace;
    margin: 2px;
}

JavaScript

const TEAMS = 10;			// number of teams
const STATIONS = 5;		// number of stations
const TEAMS_CAP = 2;	// concurent number of teams at each station

// overriding console.log, cause lazy
let console = (function() {
	const CONSOLE_LINE = "<p class=\"console-line\"></p>";
	return {
	    log: function (text) {
	        $("#console-log").append($(CONSOLE_LINE).html(text));
	    }
	};
})();

// recursively generate unique team compositions
function generate(comp, count, compositions) {
	for (let i = 1; i <= TEAMS; i++) {
  	// make a clone of the given team comp
		let new_comp = _.clone(comp);
    
    // we cannot add any team that is already there
		if (new_comp.indexOf(i) !== -1) {
    	continue;
    }
    
		// add new team to the composition
   	new_comp.push(i);
		new_comp.sort();
    
    if (count < TEAMS_CAP) {
	    // if the composition is not full yet, we will add more teams
	  	generate(new_comp, count + 1, compositions);
	  } else if (!compositions.find(el => _.isEqual(el, new_comp))) {
    	// if the composition if full, we will save it if it is unique
    	compositions.push(new_comp);
    }
	}
}

// assign teams from compositions structure to the stations
function assign(compositions, stations, teams, round) {
	// if all teams were on all stations, we are done here
	if (!teams.find(t => t.length < STATIONS)) {
		return [stations, teams];
	}

	let pointer = 0;
	
	while (++pointer < compositions.length) {
		// we clone the structures to children calls
		let new_compositions = _.cloneDeep(compositions);
		let new_stations = _.cloneDeep(stations);
		let new_teams = _.cloneDeep(teams);
		
		// try to assign the next composition
		let comp = compositions[pointer];	
		
		// find free station for this round
		let free = new_stations.find(st => !st[round]);

		// if there are no free stations, we need to move into next round
		if (!free) {
			round++;
			continue;
		}
		
		// check if any of the teams are not in this round on a different station
		if...