Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Sinterklaas</title>
</head>
<body>
  <label for="jaar">Jaar:</label> 
  <select id="jaar">
    <option>2017</option>
    <option selected>2018</option>
  </select>
  
  <label for="naam">Ik ben:</label>
  <select id="naam">
    <option value="">Kies hier je naam</option>
  </select>
  <button id="go">Wie heb ik?</button>
  
  <div id="result"></div>
</body>
</html>
 
const jaren = {
  2017: {
    klazen: [
      'a',
      'b',
      'c',
      'd',
      'e',
      'f',
      'g'
    ],
    taken: ['surprise (en een gedicht)', 'gedicht', 'gedicht']
  },
  2018: {
    klazen: [
      'b',
      'c',
      'd',
      'e',
      'g',
      'h'
    ],
    taken: ['surprise (en een gedicht)', 'gedicht', 'gedicht']
  }
};
const jaarSelect = document.getElementById('jaar');
const naamSelect = document.getElementById('naam');
const goButton = document.getElementById('go');
let seed;
window.onload = redraw;
goButton.onclick = redraw;
jaarSelect.onchange = veranderJaar;
function veranderJaar() {
  clearNaamOptions();
  redraw();
}
function redraw() {
  const {naam, jaar} = readDom();
  const {klazen, taken} = jaren[jaar];
  
  updateNaamOptions(klazen);
  
  if (!jaar || !naam) {
    display("Kies een jaar en een naam.");
    
  } else {
    const lootjes = trekLootjes(klazen, taken, jaar);
  
    display(formatResults(lootjes, taken, naam));
  }
}
function updateNaamOptions(namen) {
  const selectedIndex = naamSelect.options.selectedIndex;
  
  clearNaamOptions();
  setNaamOptions(namen);
  
  naamSelect.options.selectedIndex = selectedIndex;
}
  
function setNaamOptions(namen) {
  namen.forEach(naam => {
    const option = document.createElement('option');
    option.text = naam;
    naamSelect.options.add(option);
  });
}
function clearNaamOptions() {
  while (naamSelect.options.length > 1) {
    naamSelect.options.remove(naamSelect.options.length - 1);
  }
}
function readDom() {
  let jaar = jaarSelect.value;
  let naam = naamSelect.value;
  
  return {naam: naam, jaar: jaar};
}
function trekLootjes(klazen, taken, jaar) {  
  seed = jaar * 10000;
  
  const trekkingen = getLootjes(klazen, taken.length),
        results = distribute(trekkingen, klazen);
  
  return results;
}
function display(text) {
  document.getElementById('result').innerText = text;  
}
function formatResults(lootjes, taken, naam) {
  const mijnLootjes = lootjes[naam];
  
  if (!mijnLootjes) {
    return `Dag ${naam}... je doet dit jaar niet mee, kan dat?`;
  }
  
  return `Lieve ${naam},
Je opdrachten voor dit jaar zijn:
${formatLootjes(mijnLootjes, taken)}
Veel plezier,
Sinterklaas`
}
function formatLootjes(lootjes, taken) {
  return lootjes.map(formatLootje.bind(null, taken)).join('\n')
}
function formatLootje(taken, lootje, index) {
  return `Maak een ${taken[index]} voor ${lootje}`;
}
function distribute(trekkingen, klazen) {
  return klazen.reduce(
    (acc, naam, index) => {return {...acc, [naam]: trekkingen.map(trekking => trekking[index])}}
  , {})
}
function getLootjes(klazen, num) {
  let trekkingen = [];
  
  while (trekkingen.length < num) {
    trekkingen.push(getAcceptabeleLootjes(klazen, trekkingen));
  }
  
  return trekkingen;
}
function getAcceptabeleLootjes(klazen, eerdereTrekkingen) {
  let lootjes;
  
  do {
    lootjes = shuffleArray(klazen);
  } while (!isAcceptabel(lootjes, [klazen, ...eerdereTrekkingen]));
  
  return lootjes;
}
function isAcceptabel(lootjes, eerdereTrekkingen) {
  return eerdereTrekkingen.every(heeftAllemaalAndereLootjes.bind(null, lootjes));
}
function heeftAllemaalAndereLootjes(lootjes, eerdereTrekking) {
  return eerdereTrekking.every(
    (lootje, index) => lootjes[index] !== lootje
  );
}
function shuffleArray(inArray) {
  let array = [...inArray];
  for (let i = array.length - 1; i > 0; i--) {
    const j = randomNumberUpTo(i + 1);
    [array[i], array[j]] = [array[j], array[i]];
  }
  
  return array;
}
function randomNumberUpTo(n) {
    const x = Math.sin(seed++) * 10000,
          fractional = x - Math.floor(x);
  
    return Math.floor(fractional * n);
}
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers