Reputation: 45
I found the following code in an old Stack posting. Could someone walk me through how this code ensures that the numbers within the given range (0 - 4) are never consecutively repeated.
var getNumber = (function() {
var previous = NaN;
return function() {
var min = 0;
var max = 4 + (!isNaN(previous) ? -1 : 0);
var value = Math.floor(Math.random() * max);
if (value >= previous) {
value += 1;
}
previous = value;
return value;
};
})();
for (var i = 0; i < 100; i++) {console.log(getNumber());}
Upvotes: 1
Views: 52
Reputation: 4937
The above code demonstrates the algorithm for avoiding back-to-back repetition using the IIFE pattern of Javascript.
The algorithm for avoiding back-to-back repetition is:
Interesting points to note:
The pattern var x = function() { // some code... }()
is called the 'Immediately Invoked Function Expression (IIFE)' in Javascript.
This pattern is used for defining a variable as the result of some function that will be executed before initializing the variable.
The IIFE pattern helps achieve the desired result of generating a random number, comparing it with previous value and repeating the generation till the current value is not the same as that of the previous one.
Here is a simplified version of the code, without the unnecessary statements, that highlights the working of the IIFE pattern for the generation of the random numbers:
// File name: no-repeat-demo.js
var getNumber = (
function() {
var previous = NaN
return (
function() {
var value = Math.floor(Math.random() * 5)
while (value == previous) {
value = Math.floor(Math.random() * 5)
}
previous = value
return value
}
)
}
)()
for (var i = 0; i < 10; i++) {
console.log(getNumber())
}
Output:
>node no-repeat-demo.js
1
2
3
2
3
2
3
1
3
4
More information:
https://developer.mozilla.org/en-US/docs/Glossary/IIFE
Upvotes: 1
Reputation: 8623
var getNumber = (function() {
var previous = NaN;
return function() {
var min = 0;
// if previous is a number
// max = (4 - 1); max = 3
// if previous is not a number
// max = 4;
// Actually the max will always be 3 except the first value
var max = 4 + (!isNaN(previous) ? -1 : 0);
// value < 4 or value < 3, value will integer between 0-4, or 0-3 depend on the max number is 4 or 3
var value = Math.floor(Math.random() * max);
// value will always less than 3, except the first time less than 4
if (value >= previous) {
// value >= previous, include value = previous, so it will not repeat
value += 1; // (0 - 2) + 1 will be (1 - 3)
}
previous = value;
return value;
};
})();
for (var i = 0; i < 100; i++) {
` console.log(getNumber()); }`
Upvotes: 2