I'm trying to create a javascript function that accepts 2 parameters min
and max
and generates a random number between the two integers. That part is easy.
Where things get rough is that I need to create a conditional that says
function generateNum (min, max) {
var randNumber = Math.ceil(Math.random()*(max - min)+min);
if (randNumber === max) {
// store the result (probably in an array) and generate a new
// number with the same behavior as randNumber (e.g. it is also
// stores it's total in the array and recursively "re-generates
// a new number until max is not hit)
}
}
The idea is to recursive-ise this so that a running total of the number of max hits is stored, bined, and then returned.
For example: The script receives min / max parameters of 5/10 generateNum(5,10){}
. If the value generated by randNumber
were 5, 6, 7, 8, or 9 then there would be no recursion and the function would return that value. If the value generated by randNumber
is 10
, then the value 10
is stored in an array and the function now "re-tries" recursively (meaning that as many times as 10 is generated, then that value is stored as an additional object in the array and the function re-tries). When the process stops (which could be infinite but has a parabolically decreasing probability of repeating with each recursion). The final number (5, 6, 7, 8, 9) would be added to the total of generated max
values and the result would be returned.
Quite an unusual mathematic scenario, let me know how I can clarify if that doesn't make sense.
I'm trying to create a javascript function that accepts 2 parameters min
and max
and generates a random number between the two integers. That part is easy.
Where things get rough is that I need to create a conditional that says
function generateNum (min, max) {
var randNumber = Math.ceil(Math.random()*(max - min)+min);
if (randNumber === max) {
// store the result (probably in an array) and generate a new
// number with the same behavior as randNumber (e.g. it is also
// stores it's total in the array and recursively "re-generates
// a new number until max is not hit)
}
}
The idea is to recursive-ise this so that a running total of the number of max hits is stored, bined, and then returned.
For example: The script receives min / max parameters of 5/10 generateNum(5,10){}
. If the value generated by randNumber
were 5, 6, 7, 8, or 9 then there would be no recursion and the function would return that value. If the value generated by randNumber
is 10
, then the value 10
is stored in an array and the function now "re-tries" recursively (meaning that as many times as 10 is generated, then that value is stored as an additional object in the array and the function re-tries). When the process stops (which could be infinite but has a parabolically decreasing probability of repeating with each recursion). The final number (5, 6, 7, 8, 9) would be added to the total of generated max
values and the result would be returned.
Quite an unusual mathematic scenario, let me know how I can clarify if that doesn't make sense.
Share Improve this question edited Jun 14, 2012 at 16:10 Paul 142k28 gold badges284 silver badges271 bronze badges asked Jun 5, 2012 at 19:31 BrianBrian 3,95912 gold badges58 silver badges104 bronze badges 4- 1 So what is the "stop" condition and what is the "recurse" condition? Just write that in the code as described. – user166390 Commented Jun 5, 2012 at 19:35
-
Don't understand why you need recursion. Just use a
while
loop and a counter which you increment whenever you getmax
. Stop once you get a different number. The result is thencounter * max + randNumber
(or if you want to return an array that would be easy to create as well, but recursion is not needed either way). – Felix Kling Commented Jun 5, 2012 at 19:37 - so what exactly is the question, it seems as though you have all of the logic there? Just store the number in an array that is at a higher scope level than your function and call generateNum(min,max); right afterwards. – Mike McMahon Commented Jun 5, 2012 at 19:37
- 2 Just thought you should know that your function will return 'min' only on extremely rare occasions. There's a proper function for random numbers in the answers, though. – panda-34 Commented Jun 5, 2012 at 19:44
5 Answers
Reset to default 3That part is easy.
Not as easy as you think... The algorithm that you have is broken; it will almost never give you the minimum value. Use the Math.floor
method instead, and add one to the range:
var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;
To do this recursively is simple, just call the method from itself:
function generateNum (min, max) {
var randNumber = Math.floor(Math.random()*(max - min + 1)) + min;
if (randNumber == max) {
randNumber += generateNum(min, max);
}
return randNumber;
}
You can also solve this without recursion:
function generateNum (min, max) {
var randNumber = 0;
do {
var num = Math.floor(Math.random()*(max - min + 1)) + min;
randNumber += num;
} while (num == max);
return randNumber;
}
There is no need to use an array in either case, as you don't need the seprate values in the end, you only need the sum of the values.
I assume that you don't really need a recursive solution since you tagged this for-loop
. This will return the number of times the max number was picked:
function generateNum (min, max) {
var diff = max - min;
if(diff <= 0)
return;
for(var i = 0; diff == Math.floor(Math.random()*(diff + 1)); i++);
return i;
}
Example outputs:
generateNum(1,2) // 3
generateNum(1,2) // 1
generateNum(1,2) // 0
generateNum(5,10) // 0
generateNum(5,10) // 1
Two things:
1) the probability to roll 10 stays (theoretically the same on each roll (re-try)), the low probability is of hitting n times 10 in a row
2) I don't see why recursion is needed, what about a while loop?
var randNumber;
var arr = [];
while ((randNumber = Math.ceil(Math.random()*(max - min)+min)) === max) {
arr.push(
}
I'd consider an idea that you don't need to use not only recursion and arrays but not even a for loop. I think you need a simple expression like this one (separated into three for clarity):
function generateNum (min, max)
{
var randTail = Math.floor(Math.random()*(max - min)+min);
var randRepeatMax = Math.floor(Math.log(Math.random()) / Math.log(1/(max-min+1)));
return randRepeatMax*max + randTail;
}
Assuming one random number is as good as another, this should give you the same distribution of values as the straightforward loop.
Recursive method:
function generateNum (min, max) {
var res = Math.floor(Math.random() * (max - min + 1)) + min;
return (res === max) ? [res].concat(generateNum(min, max)) : res;
}