Skip to content

Instantly share code, notes, and snippets.

@leegcc
Created June 15, 2016 15:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leegcc/4882a42cddb97bd631636b51efcea10f to your computer and use it in GitHub Desktop.
Save leegcc/4882a42cddb97bd631636b51efcea10f to your computer and use it in GitHub Desktop.
抽奖
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());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment