Random number, which is not equal to the previous number

This answer presents three attempts

  1. A simple version with a property of the function getNumber, last, which stores the last random value.

  2. A version which uses a closure over the min and max values with raising an exception if max is smaller than min.

  3. A version which combines the closure and the idea of keeping all random values and use it as it seems appropriate.


One

You could use a property of getNumber to store the last number and use a do ... while loop.

function getNumber() {
    var min = 0,
        max = 4,
        random;

    do {
        random = Math.floor(Math.random() * (max - min)) + min;
    } while (random === getNumber.last);
    getNumber.last = random;
    return random;
};

var i;
for (i = 0; i < 100; i++) {
    console.log(getNumber());
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

Two

Another proposal with a closure over the interval and the last random value.

function setRandomInterval(min, max) {
    var last;
    if (min >= max) {
        throw 'Selected interval [' + min + ', ' + max + ') does not work for random numbers.';
    }
    return function () {
        var random;
        do {
            random = Math.floor(Math.random() * (max - min)) + min;
        } while (random === last);
        last = random;
        return random;
    };
}

var i,
    getRandom = setRandomInterval(0, 4);

for (i = 0; i < 100; i++) {
    console.log(getRandom());
}

setRandomInterval(4, 4); // throw error
.as-console-wrapper { max-height: 100% !important; top: 0; }

Three

This proposal uses the idea to minimise the call of a new random number. It works with two variables, value for the continuing same random value and count for saving the count of the same value.

The function looks first if the saved count is given and if the value is not equal with the last value. If that happens, the saved value is returned and count is decremented.

Otherwise a new random numner is generated and checked as above (first proposal). If the number is equal to the last value, the count is incremented and it goes on with generating a new random value.

As result, almost all previous generated random values are used.

function setRandomInterval(min, max) {
    var last,      // keeping the last random value
        value,     // value which is repeated selected
        count = 0, // count of repeated value
        getR = function () { return Math.floor(Math.random() * (max - min)) + min; };

    if (min >= max) {
        throw 'Selected interval [' + min + ', ' + max + ') does not work for random numbers.';
    }
    return function () {
        var random;
        if (count && value !== last) {
            --count;
            return last = value;
        }
        random = getR();
        while (random === last) {
            value = random;
            ++count;
            random = getR();
        }
        return last = random;
    };
}

var i,
    getRandom = setRandomInterval(0, 4);

for (i = 0; i < 100; i++) {
    console.log(getRandom());
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

Leave a Comment