1

I have an array like so:

var arrA = [1lemon, 2lemons, 3lemons, 1orange, 2oranges, 3oranges, 1apple, 2apples, 3apples, 1banana, 2bananas, 3bananas, 1coconut, 2coconuts, 3coconuts];

...that I am shuffling with this function:

        function shuffle(array) {
          var currentIndex = array.length, temporaryValue, randomIndex;

          // While there remain elements to shuffle...
          while (0 !== currentIndex) {

            // Pick a remaining element...
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;

            // And swap it with the current element.
            temporaryValue = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex] = temporaryValue;
          }

          return array;
        }

arrA = shuffle(arrA);

...and then I have some code to output the randomized array's fruits, one at a time, and every 4 seconds, like so:

var text = arrA;
var counter = 0;
var elem = document.getElementById("changeText");
setInterval(change, 4000);
function change() {
 elem.innerHTML = text[counter];
    counter++;
    if(counter >= text.length) { counter = 0; }
}

They will appear on a div:

<div id="changeText"><p>pick fruit(s)</p></div>

But in this manner all elements in the array will appear on each loop (they have 100% of possibilities of appearing).

How to do so they appear with a certain frequency?

So the 1fruit appear 50% of the time, the 2fruits 30% of the time, and the 3fruits 20% of the time?

Just wrapping my mind around this...

Thanks for your ideas,

0

1 Answer 1

1

I suggest to use a continuous check of the probability and the rest of the random number.

This function sets first the return value to the last possible index and iterates until the rest of the random value is smaller than the actual probability.

The probabilities have to sum to one.

function getRandomIndexByProbability(probabilities) {
    var r = Math.random(),
        index = probabilities.length - 1;

    probabilities.some(function (probability, i) {
        if (r < probability) {
            index = i;
            return true;
        }
        r -= probability;
    });
    return index;
}

function getPlural(number, word) {
    return number === 1 ? word : word + 's';
}


var i,
    fruits = ['lemon', 'orange', 'apple', 'banana', 'coconut'],
    probabilities = [0.5, 0.3, 0.2],
    count = {},
    fruit,
    value;

fruits.forEach(function (a) { 
    var i;
    for (i = 1; i <= 3; i++) {
        count[i + getPlural(i, a)] = 0;
    }
});

for (i = 0; i < 1e6; i++) {
    fruit = fruits[Math.floor(Math.random() * fruits.length)];
    value = getRandomIndexByProbability(probabilities) + 1;
    count[value + getPlural(value, fruit)]++;
}

console.log(count);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

1 Comment

Amazing, thanks! Will have to dig into the code to fully get it, but it looks brilliant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.