How to form unique tuples for a secret friend game?

Asked

Viewed 76 times

0

I am trying to create an algorithm for a secret friend draw. That is, given an array I need to form unique pairs. Example: [Gandalf, Bilbo, Thorin] a possible return would be [[Gandalf, Thorin ], [Bilbo, Gandalf], [Thorin, Bilbo]]. I tried this way:

let amigos = ['Gandalf', 'Bilbo', 'Thorin'];
let copiaAmigos = [...amigos];

console.log(amigos.map(element => {
    return [element, sorteArAmigos(element)];
}));

function sorteArAmigos(item){
    while (copiaAmigos.length) {
        let indexSorteado = sorteNumero(copiaAmigos);
        let valorSorteado = copiaAmigos[indexSorteado];
        if(valorSorteado == item){ // Acho que o erro está aqui.
            continue;
        }

        copiaAmigos.splice(indexSorteado, 1); // remove um amigo já sorteado
        return valorSorteado;
    }
}
// Função que sorteia um número do array copiaAmigos
function sorteNumero(array) {
  let numeroSorteado = Math.floor(Math.random() * array.length);
  return numeroSorteado;
}

At some point it enters an infinite loop. Why is this loop taking place, how to fix it?

1 answer

3


And why not just randomly draw the names' positions and associate each name with its successor, the latter being associated with the first?

function pairs(names)
{
  const _pairs = [];

  // Copia o array para que as alterações dentro da função não sejam
  // refletidas no array original fora da função (evita efeito colateral)
  const _names = [...names];
  
  // Sorteia aleatoriamente as posições dos nomes
  _names.sort(() => Math.random() - 0.5);


  // Associa cada nome com seu sucessor e o último com o primeiro
  for (let i = 0; i < _names.length; i++) {
    _pairs.push([_names[i], _names[(i != _names.length - 1) ? i+1 : 0]]);
  }
  
  return _pairs;
}

const names = ['Gandalf', 'Bilbo', 'Thorin'];

console.log(pairs(names));

Browser other questions tagged

You are not signed in. Login or sign up in order to post.