Created
June 15, 2016 15:26
-
-
Save leegcc/4882a42cddb97bd631636b51efcea10f to your computer and use it in GitHub Desktop.
Revisions
-
aqxa created this gist
Jun 15, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,120 @@ const AsciiTable = require("ascii-table"); class LuckyDraw { constructor(gifts) { this.gifts = gifts; } analyzeOdds() { const totalOfPriority = this.gifts.reduce((memo, gift) => memo + gift.priority, 0); return this.gifts.map(({name, quantity, priority}) => { const odds = priority / totalOfPriority * 100; return { name, quantity, priority, odds } }); } luck() { const remainingGifts = this.gifts.filter(gift => gift.quantity !== 0); const totalOfPriority = remainingGifts.reduce((memo, gift) => memo + gift.priority, 0); const randomNumber = ~~(Math.random() * totalOfPriority); let priority = 0, luckyGift = null; remainingGifts.some((gift) => { priority += gift.priority; if (priority < randomNumber) { return false; } luckyGift = gift; if (luckyGift.quantity > 0) { luckyGift.quantity--; } return true; }); return luckyGift; } } var luckyDraw = new LuckyDraw([ { name: '1000', quantity: 1, priority: 1 }, { name: '100', quantity: -1, priority: 100 }, { name: '50', quantity: -1, priority: 200 }, { name: '30', quantity: -1, priority: 300 }, { name: '20', quantity: -1, priority: 300 }, { name: '10', quantity: -1, priority: 99 } ]); const comparator = (a, b) => parseFloat(b) > parseFloat(a); const analyzedOdds = luckyDraw.analyzeOdds(); let table = new AsciiTable(); table.setHeading('Name', 'Quantity', 'Priority', 'Odds') .setAlign(1, AsciiTable.RIGHT) .setAlign(2, AsciiTable.RIGHT) .setAlign(3, AsciiTable.RIGHT); analyzedOdds.forEach(({name, quantity, priority, odds}) => { table.addRow(name, quantity, priority, odds + '%'); }); table.sortColumn(3, comparator); console.log(table.toString()); let totalOfCount = 0; const countByName = {}; for (let i = 0; i < 2000; i++) { const {name} = luckyDraw.luck(); if (!countByName.hasOwnProperty(name)) { countByName[name] = 0; } countByName[name]++; totalOfCount++; } table = new AsciiTable(); table.setHeading('Name', 'Quantity', 'Odds', 'Offset') .setAlign(1, AsciiTable.RIGHT) .setAlign(2, AsciiTable.RIGHT) .setAlign(3, AsciiTable.RIGHT); const names = Object.keys(countByName); names.forEach((key) => { const count = countByName[key]; const odds = count / totalOfCount * 100; const {odds: expectedOdds} = analyzedOdds.find(({name}) => name === key); const offset = expectedOdds - odds; table.addRow(key, count, odds + '%', offset + '%'); }); table.sortColumn(1, comparator); console.log(table.toString());