0

to make it clearer I have an array of player ids and I want to divide into X number of groups equally and randomly, but when the number is odd the group 1 need to be the subarray with the small number of parts: like this example:

  • Player ids: [1,2,3,4,5,6,7,8,9,10,11,12,13,14]
  • Number of groups: 3
  • expected result: [14,12,2,1], [3,4,8,13,11], [5,6,7,9,10]

I cases when the number is even is easier but i don't know how to achieve this case. I need some help to know how to.

3 Answers3

2

Just pick players sequentially and assign them to groups. Pseudo code:

int nextGroup = noOfGroups - 1
while players is not empty
    player = random entry in players
    remove player from players
    add player to group[nextGroup]
    nextGroup--
    if(nextGroup < 0)
        nextGroup = noOfGroups - 1
loop
Nico Schertler
  • 32,049
  • 4
  • 39
  • 70
1

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];
var i = arr.length;
var partLen = i / 3;
var parentArr = [],
  temp = [];

function shuffle(array) {
  var currentIndex = array.length,
    temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}
var shuffled = shuffle(arr);
while (i--) {
  if (temp.length >= partLen) {
    parentArr.unshift(temp);
    temp = [];
  }
  temp.push(shuffled[i]);
}
if (temp.length) {
  parentArr.unshift(temp);
  temp = [];
}
console.log(JSON.stringify(parentArr, null, 4));
Community
  • 1
  • 1
Rayon
  • 36,219
  • 4
  • 49
  • 76
1

We start with inventing an array method to properly shuffle the arrays. Afterwards our job is simple. I guess the following should do it.

Array.prototype.shuffle = function(){
  var i = this.length,
      j,
    tmp;
  while (i > 1) {
    j = Math.floor(Math.random()*i--);
    tmp = this[i];
    this[i] = this[j];
    this[j] = tmp;
  }
  return this;
};

function groupPlayers(a,n){
  var result = [],
    remnants = a.shuffle().splice(-(a.length % n) || a.length); // the ones out in the cold
  for (var i = 0, len = a.length; i < len; i += len/n ) result.push(a.slice(i,i + len/n));
  return remnants.reduce((res,e,i,a) => (res[res.length-1-i].push(e),res),result); // finding a home for remnants
}


var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14],
 result = groupPlayers(arr,3);
console.log(result);
Redu
  • 25,060
  • 6
  • 56
  • 76
  • hey man, I have a question, what operator or expression is this '=>' ? you are using it on return remnants.reduce((res,e,i,a) => (...). Im using this function inside an ionic app and when I emulate the app on ios it throws a sintax error. there is explanation for this in android works fine. – Jose Miguel Ledón Aug 31 '16 at 09:26
  • 1
    @Jose Miguel Ledón That's ES6 arrow function syntax. In other terms `x => x` means `function(x){return x}` ES6 functionalities might not work on every device yet. So you can either convert the arrow functions to their conventional equivalents or use babel.js for this job. For instance the remnants reduce callback would be like `remnants.reduce(function(res,e,i,a){ res[res.length-1-i].push(e); return res},result)` – Redu Aug 31 '16 at 09:33