const TESTS_LIST = ['Charles', 'Baruch','Frédéric', 'John', 'Dan', 'Linus', 'Nina', 'Mikhaïl', 'Russel', 'Françoise', 'Albert', 'Beth', 'Erykah', 'Aretha', 'Lucio', 'Bartleby','Zach','Patti','Aesop','Vernon'] const NOBODY = '***NOBODY'; let viewRounds; let viewParticipants; function outputChanged(val){ document.getElementById('rounds').innerHTML='' let v = val == 0 ? viewParticipants : viewRounds; document.getElementById('rounds').appendChild(v) } function groupSizeChanged(val){ let nbParticipants = document.getElementsByClassName('participant').length; let meetsPerRound = val - 1; let maxRounds = Math.floor(nbParticipants / meetsPerRound); document.getElementById('nbRounds').max = maxRounds } var participants; function loadParticipantsFileChooser(){ document.getElementById('filechooser').click() } function loadTest(){ addParticipants(TESTS_LIST) } function loadParticipantsFromFile(file){ let reader = new FileReader(); let contents = reader.readAsText(file); reader.onload = function(event) { let contents = reader.result; let lines = contents.split('\n'); addParticipants(lines) }; } function addParticipants(list){ list.forEach(function(item) { if(item.trim() !== '') addParticipant(item) }); } function addParticipant(name){ var newInput = document.createElement('input'); newInput.setAttribute('class','participant'); newInput.setAttribute('placeholder','participant'); if(name) newInput.value = name; document.getElementById('participants').appendChild(newInput) //outch... document.getElementById('nbPerGroup').disabled = false; document.getElementById('nbRounds').disabled = false; document.getElementById('btn-do-it').disabled = false; } function russellize(){ let k = document.getElementById('nbPerGroup').value let nbRounds = document.getElementById('nbRounds').value let nbGroups = Math.ceil(participants.length / k) let rounds = new Array() let missingParticipants = nbGroups * k - participants.length for(let n = 0; n < missingParticipants; n++) participants.push(NOBODY + n); let availablesPerParticipants = new Map() participants.forEach(function (p) { availablesPerParticipants.set(p,participants.slice().filter(el => el !== p)) }); for(let i = 1; i <= nbRounds; i++){ let round = new Array() let availables = participants.slice() for(let j = 0; j < nbGroups ; j++){ let currentGroup = new Array() let toTest = availables.slice() while(currentGroup.length < k){ let random = Math.floor(Math.random()*toTest.length) let randomParticipant = toTest[random] let ok = true toTest.splice(random, 1); // console.log(randomParticipant + '/' + random) currentGroup.forEach(function (p) { if(availablesPerParticipants.get(p).indexOf(randomParticipant)<0){ ok = false return } }) if(!ok && toTest.length === 0){ return false } if(ok){ let randomEq = availables.indexOf(randomParticipant) availables.splice(randomEq, 1); // console.log(availables) currentGroup.forEach(function (p) { let l = availablesPerParticipants.get(p) let index = l.indexOf(randomParticipant) l.splice(index,1) }) currentGroup.push(randomParticipant) } } round.push(currentGroup) } rounds.push(round) } return rounds } function run(){ doIt() } function doIt(){ participants = new Array() var inputs = document.getElementsByClassName('participant') for(var i = 0; i < inputs.length; i++){ participants.push(inputs[i].value) } let rounds = false let attempts = 0 while(!rounds){ attempts ++ rounds = russellize() } console.log(rounds) console.log("Attempts = " + attempts) let stats = new Map() participants.forEach(function (p) { let l = new Array() stats.set(p,l) rounds.forEach(function (round) { round.forEach(function (group) { if(group.indexOf(p)>=0){ group.forEach(function (p2) { if(p !== p2){ l.push(p2) } }) } }) }) }) document.getElementById('rounds').innerHTML='' viewParticipants = rendeParticipantTables(participants, rounds) document.getElementById('rounds').appendChild(viewParticipants) viewRounds = renderRounds(rounds) document.getElementById('participants-radio').disabled = false; document.getElementById('rounds-radio').disabled = false; } function renderRounds(rounds){ let x = 1 let roundsBlock = document.createElement('div') rounds.forEach(function (round) { let roundBlockWrap = document.createElement('div') let roundBlock = document.createElement('div') let roundTitle = document.createElement('h2') let roundTitleText = document.createTextNode('Round ' + x) roundTitle.appendChild(roundTitleText) roundBlockWrap.appendChild(roundTitle) roundBlock.classList.add('round') let y = 1 round.forEach(function (group) { let groupBlock = document.createElement('div') let groupTitle = document.createElement('h4') let groupTitleText = document.createTextNode('Group ' + y) groupTitle.append(groupTitleText) groupBlock.append(groupTitle) roundBlock.append(groupBlock) let list = document.createElement('ul') groupBlock.appendChild(list) groupBlock.classList.add('group') group.forEach(function (p) { let emptySlot = p.indexOf(NOBODY) >= 0 let item = document.createElement('li') if(emptySlot) item.classList='empty-slot' let pTxt = emptySlot ? '' : p; item.appendChild(document.createTextNode(pTxt)) list.appendChild(item) }) y ++ }) x++ roundBlockWrap.append(roundBlock) roundsBlock.appendChild(roundBlockWrap) }) return roundsBlock } function rendeParticipantTables(participants, rounds){ let participantBlocks = document.createElement('div') participantBlocks.classList.add('participant-blocks') participants.forEach(function (p) { let participantBlock = document.createElement('div') participantBlocks.appendChild(participantBlock) let participantName= document.createElement('h2') participantName.appendChild(document.createTextNode(p)) let placesBlock = document.createElement('ul') participantBlock.append(participantName) participantBlock.classList.add('participant-block') participantBlock.append(placesBlock) let roundNum = 1 rounds.forEach(function (round) { let groupNum = 1 let roundBlock = document.createElement('li') placesBlock.append(roundBlock) round.forEach(function (group) { group.forEach(function (p2) { if(p2 === p){ let roundNumSpan = document.createElement('span') roundNumSpan.classList.add('round-num') roundBlock.appendChild(roundNumSpan) roundNumSpan.appendChild(document.createTextNode("Round " + roundNum +" : ")) roundBlock.appendChild(document.createTextNode("Table " + groupNum)) } }) groupNum ++ }) roundNum ++ }) }) return participantBlocks }