// Ушло примерно 1.5 часа
// Сперва пытался сам решить, но зашел в тупик. Поэтому, пришлось погуглить
// Возвращает id баннера или null если в списке нет элемента с положительным весом
function getNextBannerID(bannerList, sumWeight) {
let rand = Math.random() * sumWeight;
for (let i = 0; i < bannerList.length; i++) {
if(rand < bannerList[i].w && rand > 0) {
return bannerList[i].id;
}
rand -= bannerList[i].w;
}
return null;
}
function main(bannerList) {
let sumWeight = bannerList.reduce((sum, banner) => sum + banner.w, 0);
let stat = {};
// Для удобства теста повторяем вызов sumWeight раз
// Количество показов каждого баннера должно быть примерно равно весу
for(let i = 0; i < sumWeight; i++) {
let nextId = getNextBannerID(bannerList, sumWeight);
// console.log(i + 1 + ':', nextId);
// Собираем и показываем статистику для удобства
if (!stat[nextId]) {
stat[nextId] = 1;
} else {
stat[nextId] += 1;
}
}
console.log('Stats:');
console.log(stat);
}
function test() {
let tests = [
[
{w: 100, id: 1},
{w: 10.1, id: 2},
{w: 50, id: 1},
],
[
{w: 100, id: 1},
{w: 200, id: 2},
{w: 400, id: 3},
{w: 800, id: 4},
],
[
{w: 0, id: 1},
]
];
tests.forEach((test, index) => {
console.log(`Test ${index + 1}:`);
console.log('Banner list', test);
main(test);
console.log('');
})
}
test();