Представьте, что вы делаете генеративный проект. Хотите, чтобы работа имела одну из 8 черт, и пишете так:
let options=['🍒','🍓','🍇','🍎','🍋','🍍','🍏','🥥',]
let optionsIndex = Math.floor(Math.random() * options.length)
let trait = options[optionsIndex]
Запускаете скрипт много раз и смотрите статистику:
let options = ["🍒", "🍓", "🍇", "🍎", "🍋", "🍍", "🍏", "🥥"];
let stats = Array(8).fill(0)
for (let i = 0; i < 100; i++) {
let optionsIndex = Math.floor(Math.random() * options.length);
let trait = options[optionsIndex];
stats[optionsIndex] ++
}
for(let i=0;i<8;i++){
console.log(options[i].repeat(stats[i]))
}
Да, вы правы, строка #5 бесполезна
Вот что получается:
🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒
🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓
🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋
🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍
🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏🍏
🥥🥥🥥🥥🥥🥥🥥🥥🥥🥥🥥🥥🥥
Яблокам повезло в этот раз
Потом вы решаете, что кокосы должны быть реже вишен. Нет, кокосы должны быть самой редкой чертой в проекте! Один на сотни! Поэтому меняете функцию random на возведённую в квадрат:
let optionsIndex = Math.floor(Math.random()**2 * options.length);
И получаете распределение вроде такого:
🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒
🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓
🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇
🍎🍎🍎🍎🍎🍎🍎
🍋🍋🍋🍋🍋🍋🍋🍋
🍍🍍🍍🍍🍍🍍🍍🍍🍍
🍏🍏🍏🍏🍏🍏
🥥🥥🥥🥥🥥🥥🥥
Яблоки в пролёте
Вишни теперь самые частые! Здорово, да? Стоп, кокос должен был быть самым редким, но он такой же редкий, как и нижняя половина списка!
Давайте посмотрим, почему так происходит:
Видите, область вишни на горизонтальной оси огромная, а область кокоса такая же широкая, как у соседей.
Виновата парабола! Нам нужен круг:
let optionsIndex = Math.floor((1-Math.sqrt(1-Math.random()**2)) * options.length);
Вот как это отличается:
Обратите внимание, какая крошечная полоска у кокоса! Запустим тест ещё раз:
🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒
🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓
🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇🍇
🍎🍎🍎🍎🍎🍎🍎
🍋🍋🍋🍋
🍍🍍🍍🍍
🍏🍏
🥥
Результаты теста кругового рандома
Нам повезло получить хотя бы один кокос, чаще всего их вообще нет.
Мы справились, кокосы теперь супер редкие, ура.