You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

252 lines
7.5 KiB

  1. const TESTS_LIST = ['Charles', 'Baruch','Frédéric', 'John', 'Dan',
  2. 'Linus', 'Nina', 'Mikhaïl', 'Russel', 'Françoise',
  3. 'Albert', 'Beth', 'Erykah', 'Aretha', 'Lucio',
  4. 'Bartleby','Zach','Patti','Aesop','Vernon']
  5. const NOBODY = '***NOBODY';
  6. let viewRounds;
  7. let viewParticipants;
  8. function outputChanged(val){
  9. document.getElementById('rounds').innerHTML=''
  10. let v = val == 0 ? viewParticipants : viewRounds;
  11. document.getElementById('rounds').appendChild(v)
  12. }
  13. function groupSizeChanged(val){
  14. let nbParticipants = document.getElementsByClassName('participant').length;
  15. let meetsPerRound = val - 1;
  16. let maxRounds = Math.floor(nbParticipants / meetsPerRound);
  17. document.getElementById('nbRounds').max = maxRounds
  18. }
  19. var participants;
  20. function loadParticipantsFileChooser(){
  21. document.getElementById('filechooser').click()
  22. }
  23. function loadTest(){
  24. addParticipants(TESTS_LIST)
  25. }
  26. function loadParticipantsFromFile(file){
  27. let reader = new FileReader();
  28. let contents = reader.readAsText(file);
  29. reader.onload = function(event) {
  30. let contents = reader.result;
  31. let lines = contents.split('\n');
  32. addParticipants(lines)
  33. };
  34. }
  35. function addParticipants(list){
  36. list.forEach(function(item) {
  37. if(item.trim() !== '')
  38. addParticipant(item)
  39. });
  40. }
  41. function addParticipant(name){
  42. var newInput = document.createElement('input');
  43. newInput.setAttribute('class','participant');
  44. newInput.setAttribute('placeholder','participant');
  45. if(name)
  46. newInput.value = name;
  47. document.getElementById('participants').appendChild(newInput)
  48. //outch...
  49. document.getElementById('nbPerGroup').disabled = false;
  50. document.getElementById('nbRounds').disabled = false;
  51. document.getElementById('btn-do-it').disabled = false;
  52. }
  53. function russellize(){
  54. let k = document.getElementById('nbPerGroup').value
  55. let nbRounds = document.getElementById('nbRounds').value
  56. let nbGroups = Math.ceil(participants.length / k)
  57. let rounds = new Array()
  58. let missingParticipants = nbGroups * k - participants.length
  59. for(let n = 0; n < missingParticipants; n++)
  60. participants.push(NOBODY + n);
  61. let availablesPerParticipants = new Map()
  62. participants.forEach(function (p) {
  63. availablesPerParticipants.set(p,participants.slice().filter(el => el !== p))
  64. });
  65. for(let i = 1; i <= nbRounds; i++){
  66. let round = new Array()
  67. let availables = participants.slice()
  68. for(let j = 0; j < nbGroups ; j++){
  69. let currentGroup = new Array()
  70. let toTest = availables.slice()
  71. while(currentGroup.length < k){
  72. let random = Math.floor(Math.random()*toTest.length)
  73. let randomParticipant = toTest[random]
  74. let ok = true
  75. toTest.splice(random, 1);
  76. // console.log(randomParticipant + '/' + random)
  77. currentGroup.forEach(function (p) {
  78. if(availablesPerParticipants.get(p).indexOf(randomParticipant)<0){
  79. ok = false
  80. return
  81. }
  82. })
  83. if(!ok && toTest.length === 0){
  84. return false
  85. }
  86. if(ok){
  87. let randomEq = availables.indexOf(randomParticipant)
  88. availables.splice(randomEq, 1);
  89. // console.log(availables)
  90. currentGroup.forEach(function (p) {
  91. let l = availablesPerParticipants.get(p)
  92. let index = l.indexOf(randomParticipant)
  93. l.splice(index,1)
  94. })
  95. currentGroup.push(randomParticipant)
  96. }
  97. }
  98. round.push(currentGroup)
  99. }
  100. rounds.push(round)
  101. }
  102. return rounds
  103. }
  104. function run(){
  105. doIt()
  106. }
  107. function doIt(){
  108. participants = new Array()
  109. var inputs = document.getElementsByClassName('participant')
  110. for(var i = 0; i < inputs.length; i++){
  111. participants.push(inputs[i].value)
  112. }
  113. let rounds = false
  114. let attempts = 0
  115. while(!rounds){
  116. attempts ++
  117. rounds = russellize()
  118. }
  119. console.log(rounds)
  120. console.log("Attempts = " + attempts)
  121. let stats = new Map()
  122. participants.forEach(function (p) {
  123. let l = new Array()
  124. stats.set(p,l)
  125. rounds.forEach(function (round) {
  126. round.forEach(function (group) {
  127. if(group.indexOf(p)>=0){
  128. group.forEach(function (p2) {
  129. if(p !== p2){
  130. l.push(p2)
  131. }
  132. })
  133. }
  134. })
  135. })
  136. })
  137. document.getElementById('rounds').innerHTML=''
  138. viewParticipants = rendeParticipantTables(participants, rounds)
  139. document.getElementById('rounds').appendChild(viewParticipants)
  140. viewRounds = renderRounds(rounds)
  141. document.getElementById('participants-radio').disabled = false;
  142. document.getElementById('rounds-radio').disabled = false;
  143. }
  144. function renderRounds(rounds){
  145. let x = 1
  146. let roundsBlock = document.createElement('div')
  147. rounds.forEach(function (round) {
  148. let roundBlockWrap = document.createElement('div')
  149. let roundBlock = document.createElement('div')
  150. let roundTitle = document.createElement('h2')
  151. let roundTitleText = document.createTextNode('Round ' + x)
  152. roundTitle.appendChild(roundTitleText)
  153. roundBlockWrap.appendChild(roundTitle)
  154. roundBlock.classList.add('round')
  155. let y = 1
  156. round.forEach(function (group) {
  157. let groupBlock = document.createElement('div')
  158. let groupTitle = document.createElement('h4')
  159. let groupTitleText = document.createTextNode('Group ' + y)
  160. groupTitle.append(groupTitleText)
  161. groupBlock.append(groupTitle)
  162. roundBlock.append(groupBlock)
  163. let list = document.createElement('ul')
  164. groupBlock.appendChild(list)
  165. groupBlock.classList.add('group')
  166. group.forEach(function (p) {
  167. let emptySlot = p.indexOf(NOBODY) >= 0
  168. let item = document.createElement('li')
  169. if(emptySlot)
  170. item.classList='empty-slot'
  171. let pTxt = emptySlot ? '' : p;
  172. item.appendChild(document.createTextNode(pTxt))
  173. list.appendChild(item)
  174. })
  175. y ++
  176. })
  177. x++
  178. roundBlockWrap.append(roundBlock)
  179. roundsBlock.appendChild(roundBlockWrap)
  180. })
  181. return roundsBlock
  182. }
  183. function rendeParticipantTables(participants, rounds){
  184. let participantBlocks = document.createElement('div')
  185. participantBlocks.classList.add('participant-blocks')
  186. participants.forEach(function (p) {
  187. let participantBlock = document.createElement('div')
  188. participantBlocks.appendChild(participantBlock)
  189. let participantName= document.createElement('h2')
  190. participantName.appendChild(document.createTextNode(p))
  191. let placesBlock = document.createElement('ul')
  192. participantBlock.append(participantName)
  193. participantBlock.classList.add('participant-block')
  194. participantBlock.append(placesBlock)
  195. let roundNum = 1
  196. rounds.forEach(function (round) {
  197. let groupNum = 1
  198. let roundBlock = document.createElement('li')
  199. placesBlock.append(roundBlock)
  200. round.forEach(function (group) {
  201. group.forEach(function (p2) {
  202. if(p2 === p){
  203. let roundNumSpan = document.createElement('span')
  204. roundNumSpan.classList.add('round-num')
  205. roundBlock.appendChild(roundNumSpan)
  206. roundNumSpan.appendChild(document.createTextNode("Round " + roundNum +" : "))
  207. roundBlock.appendChild(document.createTextNode("Table " + groupNum))
  208. }
  209. })
  210. groupNum ++
  211. })
  212. roundNum ++
  213. })
  214. })
  215. return participantBlocks
  216. }