I have a bit weird requirement where I need to generate Random numbers of the length that is given by user. User can give Minimum Length and the Maximum Length and I need to generate the random numbers which consist of the character length between this range.
For example if the Minimum Length is 6 and Maximum Length is 10 then I need to generate the random numbers whose number of characters has to be between the range 6 and 10. For this example following can be the random generators:
123456,
7654321,
12345678,
987654321,
5432109876, etc.
Like this the Random generators has to contain the length which is between the provided inputs.
I know how to create random numbers between a range and based on fixed character length but I don't know how to created based on variable length. I tried finding the answers but most of them are based on the fixed length and fixed range, could not find the exact match that I am looking for.
It would be really great if someone can help me with this.
You may produce an array (Array.from() of randomly chosen length in the range of minLen and maxLen) and populate that with random digits in the range 1 through 9, then Array.prototype.join() the array into string and convert to number:
const randomNum = (minLen, maxLen) =>
+Array
.from(
{length: 0|Math.random()*(maxLen-minLen+1)+minLen},
() => 0|Math.random()*9+1
)
.join('')
console.log(randomNum(3,7))
You could generate the range and get the random values from that range.
For example
min = 2
max = 4
rangeMin = 10
rangeMax = 10000
const
getRandom = (min, max) => Math.floor(Math.random() * (max - min)) + min,
getRandomX = (min, max) => getRandom(10 ** (min - 1), 10 ** max);
let min = Infinity,
max = -Infinity;
for (let i = 0; i < 1e6; i++) {
let r = getRandomX(6, 10);
if (min > r) min = r;
if (max < r) max = r;
}
console.log(min, max);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Other solutions generate randoms for each digit and join them together to form a number. This is unnecessary. We know that a number with at least m-th digits is at least 10m - 1. Similarly, having at most n digits means that the number is smaller than 10n.
const randomWithinRange = (min, max) => Math.floor(Math.random() * (max - min) + min);
const randomWithMagnitude = (min, max) => randomWithinRange(Math.pow(10, min - 1), Math.pow(10, max));
const arr = Array(100000).fill().map(() => randomWithMagnitude(6, 10)).sort((a, b) => a - b);
console.log(arr.slice(0, 100).join(", "));
console.log(arr.slice(99900, 100000).join(", "));
Note: I've sorted the 100.000-sized array just to show you the smallest and largest numbers generated.
Try this:
var minLength = 6;
var maxLength = 10;
var generatedNumbers = [];
for(var i=minLength ; i<=maxLength; i++){
var num = "";
for(var j=1;j<=i;j++){
num = num + Math.floor(Math.random(10) * 10);
}
generatedNumbers.push(num);
}
console.log(generatedNumbers);
Edit
var minLength = 1;
var maxLength = randomNumber;
var generatedNumbers = [];
for(var i=minLength ; i<=maxLength; i++){
var num = "";
for(var j=1;j<=i;j++){
num = num + Math.floor(Math.random(10) * 10);
}
generatedNumbers.push(num);
}
console.log(generatedNumbers);
this will help.
Thanks a lot, everyone for the answer. Here is the approach that I have used.
If the random numbers with just Numeric is required:
var charset = "0123456789";
var max_Length = 5;
var min_Length = 10;
var charPicker = Math.floor(Math.random() * (max_Length - min_Length + 1) + min_Length);
var randomId;
for (var i = 0; i < charPicker; i++)
{
randomId += charset.charAt(Math.floor(Math.random() * charset.length));
}
console.log(randomId);
Change the character set for Alphanumeric and Alphanumeric with URL specific characters like this:
var charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~()'!*:#,;";
While I was solving a question saying "add odd numbers from 1 to 20", I coded this:
var i, sum=0;
for (i=2; i<=20; i*2){
sum=sum+i;
}
document.write(sum);
When I launched it through a browser, it did not work. However, when I fixed i*2 into i+=2, it worked.
What am I missing? Am I not able to use *(multiplier) in For Loops?
If you need to add odd numbers from 1 to 20, then you need i+=2 as the third parameter of the for and need to initialize the variable to 1 to get the correct result:
var sum = 0;
for (var i = 1; i <= 20; i += 2) {
sum += i;
}
When you have
i += 2
2 is added to i and the result is stored into i. When you tried
var i, sum=0;
for (i=2; i<=20; i*2){
sum=sum+i;
}
i*2 calculates the value which is twice as big as i, but it will not change the value of i, so this would "work" instead:
var i, sum=0;
for (i=2; i<=20; i*=2){
sum=sum+i;
}
where
i *= 2
not only calculates the value twice as big as i, but stores the result into i as well. However, even though this will run, the result will not be correct, since you are using the wrong formula.
Also, you can calculate the result without using a for:
1 + 2 + ... + n = n * (n + 1) / 2
Assuming that n is pair: and since we know that we are "missing" half the numbers and all the pair numbers are bigger exactly with 1 than the previous impair numbers, we can subtract half of the sequence
n * (n + 1) / 2 - n / 2 = (n * (n + 1) - n) / 2 = (n * (n + 1 - 1)) /
2 = n * n / 2
and now we have exactly the double value of what we need, so the final formula is:
sum = n * n / 4;
Let's make this a function
function getOddSumUpTo(limit) {
if (limit % 2) limit ++;
return limit * limit / 4;
}
and then:
var sum = getOddSumUpTo(20);
Note that we increment limit if it is odd.
The issue is that you're not updating the value of the i in the for loop.
I want add odd numbers from 1 to 20
Then you need to change the initial value of i to 1.
var i, sum = 0;
for (i = 1; i <= 20; i += 2){
sum += i;
}
document.write(sum);
Also, you can find the sum of odd numbers from 1 to 20 by using a formula.
n = 20;
console.log(n % 2 == 0 ? (n * n)/ 4 : ((n + 1) * (n + 1))/4);
You can you just have to do it simillary to what you've written about sum.
You used there i += 2 and not i + 2.
The same way just change i * 2 to i *= 2.
Here is an working example
var i, sum = 0;
for (i = 2; i <= 20; i *= 2) {
console.log(i);
sum += i;
}
document.write(sum);
But a couple of things here.
First of all you wrote
add odd numbers from 1 to 20
and in all your examples you use sum on even numbers.
Secondly, by multiplying you will not achieve your desired goal (as you can see in a snippet above in a console)
So to actually
add odd numbers from 1 to 20
you should do it like this:
var i, sum = 0;
for (i = 1; i <= 20; i += 2) {
console.log(i);
sum += i;
}
document.write(sum);
EDIT
If you want to add even numbers you still can't use multiplying.
Why? Simply because you said yourself that you want a sum of numbers.
So let's say that we start with 2.
If we multiply it by 2 it has the value 4 which is fine.
But now look what happens in the next iteration. Our variable i which has the value 4 is multiplied by 2 and now its new value is 8. So what about 6?
Next iteration multiply 8 by 2 and its new value is 16.
Do you see where this is going?
And when you use i += 2 instead of i *= 2?
So if we start with 2 and than we add 2 its new value is 4.
In next iteration we add 2 to 4 and we have 6.
And so on.
If you want to test it, here is an example with multiplying and adding.
Pay attention to console logs
var i;
console.log("Multiplying");
for (i = 2; i <= 20; i *= 2) {
console.log("i value is: " + i);
}
console.log("Adding");
for (i = 2; i <= 20; i += 2) {
console.log("i value is: " + i);
}
What you are looking is this :
let sum = 0;
for(var i = 2; i <= 20; i += 2){
sum += i;
}
document.write(sum)
Another take on this :
// set to n (what you want). Set to n + 1
var N = 21;
// The main driver code create an array from 0-(N-1) and removes all even nums
let a = Array.apply(null, {length: N}).map(Number.call, _ => +_).filter(_=>_%2)
// console.log the array
console.log(a)
You can use whatever expression in loop header, even this is a valid for loop statement for (;;) which simply runs forever (equivalent to while(true)).
Problem is that you are not updating the i counter in for (i=2; i<=20; i*2) so the i will stays the same throughout the execution of the loop.
If you change it to for (i=2; i<=20; i = i*2) or for (i=2; i<=20; i *=2) then it will work.
It is the same as if you did
let i = 1;
i * 2;
console.log(i);
i = i * 2;
console.log(i);
The first i * 2 doesn't update the i while the second one does.
You can also translate the for loop into while loop to see the error more clearly.
// wrong
let i = 1;
while(i <= 20) {
i * 2;
// do something
}
// right
let i = 1;
while(i <= 20) {
i = i * 2 // or i *= 2
// do something
}
Just a side note, if you wanted to perform sum on more types of sequences efficiently than you could use a generator based approach and write your sum function and describe each type of a sequence with a generator function.
function *generateOdd(start, end) {
for (let i = start; i <= end; i++) {
if (i % 2 === 1) { yield i; }
}
}
function *generateEven(start, end) {
for (let i = start; i <= end; i++) {
if (i % 2 === 0) { yield i; }
}
}
function sumNums(gen, start, end) {
const generator = gen(start, end);
let res = 0;
let item = generator.next();
while (!item.done) {
res += item.value;
item = generator.next();
}
return res;
}
console.log(sumNums(generateOdd, 0, 20));
console.log(sumNums(generateEven, 0, 20));
/* sum of the Odd number using loop */
function sumOfOddNumbers(n){
let sum= 0;
for(let i = 1; i <= n; i++) {
if(i % 2 !== 0){
sum = sum + i;
}
}
return sum;
}
// 567 = 1+3+5+7+9+11+13+15+17+19+21+23+25+27+29+31+33+35+37+39+41+43+45+47
let n = 47;
let sum = sumOfOddNumbers(47);
alert('sumOfOddNumbers(' + n + ') = ' + sum);
i got stucked in a chalenge in codeFights.my code pass the simple test and fail in just 2 from five of hidden tests her is the chalenge instruction:
Ratiorg got statues of different sizes as a present from CodeMaster for his birthday, each statue having an non-negative integer size. Since he likes to make things perfect, he wants to arrange them from smallest to largest so that each statue will be bigger than the previous one exactly by 1. He may need some additional statues to be able to accomplish that. Help him figure out the minimum number of additional statues needed.
Example
For statues = [6, 2, 3, 8], the output should be
makeArrayConsecutive2(statues) = 3.
Ratiorg needs statues of sizes 4, 5 and 7.
Input/Output
[time limit] 4000ms (js)
[input] array.integer statues
An array of distinct non-negative integers.
Constraints:
1 ≤ statues.length ≤ 10,
0 ≤ statues[i] ≤ 20.
[output] integer
The minimal number of statues that need to be added to existing statues such that it contains every integer size from an interval [L, R] (for some L, R) and no other sizes.
and here is my code :
function makeArrayConsecutive2(statues) {
//range the table from min to max
var rang=statues.sort();
var some=0;
//if the table is one element
if(rang.length-1==0){
return 0;
}else{
//if the table contain more then one element
for(i=0;i<=rang.length-2;i++){
//add the deference of two consecutive position -1
//to find the number of missing numbers
some+=(rang[i+1]-rang[i]-1);
}
return some;
}
}
Everything is correct, except the sorting part.
You have used sort function to sort the array in increasing order
var rang = statues.sort();
But if sort function is not provided a compare function, it converts its elements in strings and then sort it in unicode order.
For eg: [2,1,11] will be sorted as [1,11,2] which will give undesired output.
Correct way is
var rang = statues.sort(function (a, b){
return (a - b)
});
SO THE LOGIC TO SOLVE THIS QUESTION IS:
Find the Smallest and Largest Element in Array.
Get the count of can say, difference of Largest and Smallest value of array in order to calculate, how many elements must be there to make it as a continuous array
. Like from 5 to 9, count of total elements must be 5 ( i.e.5,6,7,8,9) and also add 1 to the result to make count inclusive.
Find the Length of the Array
Subtract the count i.e. "difference of largest and smallest value " with the length of array
PYTHON CODE (For explanation):
def makeArrayConsecutive2(statues):
max_height = max(statues)
min_height = min(statues)
array_length = len(statues)
count_of_element = max_height - min_height + 1
# '1 ' is added to make it inclusive
return count_of_element-array_length
and Python one liner :
def makeArrayConsecutive2(statues):
return max(statues)-min(statues)-len(statues)+1
I agree with Deepak's Solution. The question is ready not about sorting but helping to figure out the minimum number of additional statues needed. You only need to get the max and min values.
int makeArrayConsecutive2(int[] statues)
{
int min=Integer.MAX_VALUE,max=-1;
for(int i=0;i<statues.length;i++)
{
if(statues[i] < min){ min = statues[i]; }
if(statues[i] > max){ max = statues[i]; }
}
return (max-min)+1 - statues.length;
}
Solution in typescript. Create a new array from the min and max from the status array using a for loop. Subtract new array length with status array length.
function makeArrayConsecutive2(statues: number[]): number {
let min = Math.min(...statues);
let max = Math.max(...statues);
let arr = [];
for (let i = min; i <= max; i++) {
arr.push(i);
}
return arr.length - statues.length;
}
function makeArrayConsecutive2(statues) {
const nums = [];
for (let i = Math.min(...statues); i <= Math.max(...statues); i++) {
if (!statues.includes(i)) {
nums.push(i);
}
}
return nums.length;
}
console.log(makeArrayConsecutive2([6, 2, 3, 8]))
Sorting (nlogn)is not required. Below is the solution in Java.
int makeArrayConsecutive2(int[] statues) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = 0; i < statues.length; i++) {
max = Math.max(max, statues[i]);
min = Math.min(min, statues[i]);
}
return (max - min) + 1 - statues.length;
}
This Code works
var statues = [2, 3, 6, 8];
var newStatues = [];
Function declaration
function makeArrayConsecutive2(statues) {
statues.sort(function(a, b) { return a - b });
for(var i = statues[0]; i <= statues[statues.length-1]; i++) {
newStatues.push(i);
}
return console.log(newStatues.length - statues.length);
}
Function Calling
makeArrayConsecutive2(statues);
Best solution goes here in just O(1) complexity:
let n = statues.length;
let max = Math.max.apply(null, statues);
let min = Math.min.apply(null, statues);
return max - min - n + 1;
function makeArrayConsecutive2(statues) {
var rang = statues.sort(function (a, b){
return (a - b)
});
var some=0;
if(rang.length-1==0){
return 0;
}else{
for(i=0;i<=rang.length-2;i++){
some+=(rang[i+1]-rang[i]-1);
}
return some;
}
}
function makeArrayConsecutive2(statues) {
const n = statues.length;
const min = Math.min(...statues);
const max = Math.max(...statues);
return max - min - n + 1;
}
If we subtract the minimum from the maximum element, then we get the number of elements that should be in the final array. Now subtract the already existing number of elements from this amount and add 1, then we get the result we need - the number of missing elements
Just for fun in C#
static int makeArrayConsecutive2(int[] statues)
{
List<int> ConsecutiveNums = new List<int>();
for(int i = statues.Min(); i != statues.Max() + 1; i++)
ConsecutiveNums.Add(i);
return ConsecutiveNums.Count - statues.Length;
}
function makeArrayConsecutive2(statues) {
return Math.max(...statues) - Math.min(...statues) + 1 -(statues.length)
}
I don't think we need a Looping there, that's my solution
you can try using for loop and ternary operation by the following code
def makeArrayConsecutive2(statues):
count=0
for i in range (min(statues),max(statues)):
count=count+1 if i not in statues else count
return count
function makeArrayConsecutive2(statues) {
s = statues.sort(function(a, b){return a - b});
n = statues.length;
val = 0;
for (let i=0;i<n-1;i++) {
val += (Math.abs(s[i]-s[i+1]))-1;
}
return val;
}
sort(statues.begin(), statues.end());
int count = 0;
for(int i = 1;i<statues.size(); i++){
int diff = statues[i]-statues[i-1];
if(diff>1){
count+=diff-1;
}
}
return count;
Solution in PHP
function solution($statues) {
return max($statues) - min($statues) - count($statues) + 1;
}
PHP solution for question.
function solution($statues) {
sort($statues);
$missing = 0;
$lowest = min($statues);
$highest = max($statues);
$numbers = range($lowest, $highest);
foreach($numbers as $number){
if(!in_array($number, $statues)){
$missing++;
}
}
return $missing;
}
here is code in python
def solution(statues):
statues.sort()
c = 0
for i in range(len(statues)-1):
if statues[i+1]-statues[i] > 1:
c += statues[i+1]-statues[i] -1
return (c)
How can I generate random whole numbers between two specified variables in JavaScript, e.g. x = 4 and y = 8 would output any of 4, 5, 6, 7, 8?
There are some examples on the Mozilla Developer Network page:
/**
* Returns a random number between min (inclusive) and max (exclusive)
*/
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
/**
* Returns a random integer between min (inclusive) and max (inclusive).
* The value is no lower than min (or the next integer greater than min
* if min isn't an integer) and no greater than max (or the next integer
* lower than max if max isn't an integer).
* Using Math.round() will give you a non-uniform distribution!
*/
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Here's the logic behind it. It's a simple rule of three:
Math.random() returns a Number between 0 (inclusive) and 1 (exclusive). So we have an interval like this:
[0 .................................... 1)
Now, we'd like a number between min (inclusive) and max (exclusive):
[0 .................................... 1)
[min .................................. max)
We can use the Math.random to get the correspondent in the [min, max) interval. But, first we should factor a little bit the problem by subtracting min from the second interval:
[0 .................................... 1)
[min - min ............................ max - min)
This gives:
[0 .................................... 1)
[0 .................................... max - min)
We may now apply Math.random and then calculate the correspondent. Let's choose a random number:
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
So, in order to find x, we would do:
x = Math.random() * (max - min);
Don't forget to add min back, so that we get a number in the [min, max) interval:
x = Math.random() * (max - min) + min;
That was the first function from MDN. The second one, returns an integer between min and max, both inclusive.
Now for getting integers, you could use round, ceil or floor.
You could use Math.round(Math.random() * (max - min)) + min, this however gives a non-even distribution. Both, min and max only have approximately half the chance to roll:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
With max excluded from the interval, it has an even less chance to roll than min.
With Math.floor(Math.random() * (max - min +1)) + min you have a perfectly even distribution.
min... min+1... ... max-1... max.... (max+1 is excluded from interval)
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘ ← Math.floor()
min min+1 max-1 max
You can't use ceil() and -1 in that equation because max now had a slightly less chance to roll, but you can roll the (unwanted) min-1 result too.
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
Math.random()
Returns an integer random number between min (included) and max (included):
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Or any random number between min (included) and max (not included):
function randomNumber(min, max) {
return Math.random() * (max - min) + min;
}
Useful examples (integers):
// 0 -> 10
Math.floor(Math.random() * 11);
// 1 -> 10
Math.floor(Math.random() * 10) + 1;
// 5 -> 20
Math.floor(Math.random() * 16) + 5;
// -10 -> (-2)
Math.floor(Math.random() * 9) - 10;
** And always nice to be reminded (Mozilla):
Math.random() does not provide cryptographically secure random
numbers. Do not use them for anything related to security. Use the Web
Crypto API instead, and more precisely the
window.crypto.getRandomValues() method.
Use:
function getRandomizer(bottom, top) {
return function() {
return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
}
}
Usage:
var rollDie = getRandomizer( 1, 6 );
var results = ""
for ( var i = 0; i<1000; i++ ) {
results += rollDie() + " "; // Make a string filled with 1000 random numbers in the range 1-6.
}
Breakdown:
We are returning a function (borrowing from functional programming) that when called, will return a random integer between the the values bottom and top, inclusive. We say 'inclusive' because we want to include both bottom and top in the range of numbers that can be returned. This way, getRandomizer( 1, 6 ) will return either 1, 2, 3, 4, 5, or 6.
('bottom' is the lower number, and 'top' is the greater number)
Math.random() * ( 1 + top - bottom )
Math.random() returns a random double between 0 and 1, and if we multiply it by one plus the difference between top and bottom, we'll get a double somewhere between 0 and 1+b-a.
Math.floor( Math.random() * ( 1 + top - bottom ) )
Math.floor rounds the number down to the nearest integer. So we now have all the integers between 0 and top-bottom. The 1 looks confusing, but it needs to be there because we are always rounding down, so the top number will never actually be reached without it. The random decimal we generate needs to be in the range 0 to (1+top-bottom) so we can round down and get an integer in the range 0 to top-bottom:
Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
The code in the previous example gave us an integer in the range 0 and top-bottom, so all we need to do now is add bottom to that result to get an integer in the range bottom and top inclusive. :D
NOTE: If you pass in a non-integer value or the greater number first you'll get undesirable behavior, but unless anyone requests it I am not going to delve into the argument checking code as it’s rather far from the intent of the original question.
All these solutions are using way too much firepower. You only need to call one function: Math.random();
Math.random() * max | 0;
This returns a random integer between 0 (inclusive) and max (non-inclusive).
Return a random number between 1 and 10:
Math.floor((Math.random()*10) + 1);
Return a random number between 1 and 100:
Math.floor((Math.random()*100) + 1)
function randomRange(min, max) {
return ~~(Math.random() * (max - min + 1)) + min
}
Alternative if you are using Underscore.js you can use
_.random(min, max)
If you need a variable between 0 and max, you can use:
Math.floor(Math.random() * max);
The other answers don't account for the perfectly reasonable parameters of 0 and 1. Instead you should use the round instead of ceil or floor:
function randomNumber(minimum, maximum){
return Math.round( Math.random() * (maximum - minimum) + minimum);
}
console.log(randomNumber(0,1)); # 0 1 1 0 1 0
console.log(randomNumber(5,6)); # 5 6 6 5 5 6
console.log(randomNumber(3,-1)); # 1 3 1 -1 -1 -1
Cryptographically strong
To get a cryptographically strong random integer number in the range [x,y], try:
let cs = (x,y) => x + (y - x + 1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32 | 0
console.log(cs(4, 8))
Here's what I use to generate random numbers.
function random(min,max) {
return Math.floor((Math.random())*(max-min+1))+min;
}
Math.random() returns a number between 0 (inclusive) and 1 (exclusive). We multiply this number by the range (max-min). This results in a number between 0 (inclusive), and the range.
For example, take random(2,5). We multiply the random number 0≤x<1 by the range (5-2=3), so we now have a number, x where 0≤x<3.
In order to force the function to treat both the max and min as inclusive, we add 1 to our range calculation: Math.random()*(max-min+1). Now, we multiply the random number by the (5-2+1=4), resulting in an number, x, such that 0≤x<4. If we floor this calculation, we get an integer: 0≤x≤3, with an equal likelihood of each result (1/4).
Finally, we need to convert this into an integer between the requested values. Since we already have an integer between 0 and the (max-min), we can simply map the value into the correct range by adding the minimum value. In our example, we add 2 our integer between 0 and 3, resulting in an integer between 2 and 5.
Use this function to get random numbers in a given range:
function rnd(min, max) {
return Math.floor(Math.random()*(max - min + 1) + min);
}
Here is the Microsoft .NET Implementation of the Random class in JavaScript—
var Random = (function () {
function Random(Seed) {
if (!Seed) {
Seed = this.milliseconds();
}
this.SeedArray = [];
for (var i = 0; i < 56; i++)
this.SeedArray.push(0);
var num = (Seed == -2147483648) ? 2147483647 : Math.abs(Seed);
var num2 = 161803398 - num;
this.SeedArray[55] = num2;
var num3 = 1;
for (var i_1 = 1; i_1 < 55; i_1++) {
var num4 = 21 * i_1 % 55;
this.SeedArray[num4] = num3;
num3 = num2 - num3;
if (num3 < 0) {
num3 += 2147483647;
}
num2 = this.SeedArray[num4];
}
for (var j = 1; j < 5; j++) {
for (var k = 1; k < 56; k++) {
this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55];
if (this.SeedArray[k] < 0) {
this.SeedArray[k] += 2147483647;
}
}
}
this.inext = 0;
this.inextp = 21;
Seed = 1;
}
Random.prototype.milliseconds = function () {
var str = new Date().valueOf().toString();
return parseInt(str.substr(str.length - 6));
};
Random.prototype.InternalSample = function () {
var num = this.inext;
var num2 = this.inextp;
if (++num >= 56) {
num = 1;
}
if (++num2 >= 56) {
num2 = 1;
}
var num3 = this.SeedArray[num] - this.SeedArray[num2];
if (num3 == 2147483647) {
num3--;
}
if (num3 < 0) {
num3 += 2147483647;
}
this.SeedArray[num] = num3;
this.inext = num;
this.inextp = num2;
return num3;
};
Random.prototype.Sample = function () {
return this.InternalSample() * 4.6566128752457969E-10;
};
Random.prototype.GetSampleForLargeRange = function () {
var num = this.InternalSample();
var flag = this.InternalSample() % 2 == 0;
if (flag) {
num = -num;
}
var num2 = num;
num2 += 2147483646.0;
return num2 / 4294967293.0;
};
Random.prototype.Next = function (minValue, maxValue) {
if (!minValue && !maxValue)
return this.InternalSample();
var num = maxValue - minValue;
if (num <= 2147483647) {
return parseInt((this.Sample() * num + minValue).toFixed(0));
}
return this.GetSampleForLargeRange() * num + minValue;
};
Random.prototype.NextDouble = function () {
return this.Sample();
};
Random.prototype.NextBytes = function (buffer) {
for (var i = 0; i < buffer.length; i++) {
buffer[i] = this.InternalSample() % 256;
}
};
return Random;
}());
Use:
var r = new Random();
var nextInt = r.Next(1, 100); // Returns an integer between range
var nextDbl = r.NextDouble(); // Returns a random decimal
I wanted to explain using an example:
Function to generate random whole numbers in JavaScript within a range of 5 to 25
General Overview:
(i) First convert it to the range - starting from 0.
(ii) Then convert it to your desired range ( which then will be very
easy to complete).
So basically, if you want to generate random whole numbers from 5 to 25 then:
First step: Converting it to range - starting from 0
Subtract "lower/minimum number" from both "max" and "min". i.e
(5-5) - (25-5)
So the range will be:
0-20 ...right?
Step two
Now if you want both numbers inclusive in range - i.e "both 0 and 20", the equation will be:
Mathematical equation: Math.floor((Math.random() * 21))
General equation: Math.floor((Math.random() * (max-min +1)))
Now if we add subtracted/minimum number (i.e., 5) to the range - then automatically we can get range from 0 to 20 => 5 to 25
Step three
Now add the difference you subtracted in equation (i.e., 5) and add "Math.floor" to the whole equation:
Mathematical equation: Math.floor((Math.random() * 21) + 5)
General equation: Math.floor((Math.random() * (max-min +1)) + min)
So finally the function will be:
function randomRange(min, max) {
return Math.floor((Math.random() * (max - min + 1)) + min);
}
After generating a random number using a computer program, it is still considered as a random number if the picked number is a part or the full one of the initial one. But if it was changed, then mathematicians do not accept it as a random number and they can call it a biased number.
But if you are developing a program for a simple task, this will not be a case to consider. But if you are developing a program to generate a random number for a valuable stuff such as lottery program, or gambling game, then your program will be rejected by the management if you are not consider about the above case.
So for those kind of people, here is my suggestion:
Generate a random number using Math.random() (say this n):
Now for [0,10) ==> n*10 (i.e. one digit) and for[10,100) ==> n*100 (i.e., two digits) and so on. Here square bracket indicates that the boundary is inclusive and a round bracket indicates the boundary is exclusive.
Then remove the rest after the decimal point. (i.e., get the floor) - using Math.floor(). This can be done.
If you know how to read the random number table to pick a random number, you know the above process (multiplying by 1, 10, 100 and so on) does not violate the one that I was mentioned at the beginning (because it changes only the place of the decimal point).
Study the following example and develop it to your needs.
If you need a sample [0,9] then the floor of n10 is your answer and if you need [0,99] then the floor of n100 is your answer and so on.
Now let’s enter into your role:
You've asked for numbers in a specific range. (In this case you are biased among that range. By taking a number from [1,6] by roll a die, then you are biased into [1,6], but still it is a random number if and only if the die is unbiased.)
So consider your range ==> [78, 247]
number of elements of the range = 247 - 78 + 1 = 170; (since both the boundaries are inclusive).
/* Method 1: */
var i = 78, j = 247, k = 170, a = [], b = [], c, d, e, f, l = 0;
for(; i <= j; i++){ a.push(i); }
while(l < 170){
c = Math.random()*100; c = Math.floor(c);
d = Math.random()*100; d = Math.floor(d);
b.push(a[c]); e = c + d;
if((b.length != k) && (e < k)){ b.push(a[e]); }
l = b.length;
}
console.log('Method 1:');
console.log(b);
/* Method 2: */
var a, b, c, d = [], l = 0;
while(l < 170){
a = Math.random()*100; a = Math.floor(a);
b = Math.random()*100; b = Math.floor(b);
c = a + b;
if(c <= 247 || c >= 78){ d.push(c); }else{ d.push(a); }
l = d.length;
}
console.log('Method 2:');
console.log(d);
Note: In method one, first I created an array which contains numbers that you need and then randomly put them into another array.
In method two, generate numbers randomly and check those are in the range that you need. Then put it into an array. Here I generated two random numbers and used the total of them to maximize the speed of the program by minimizing the failure rate that obtaining a useful number. However, adding generated numbers will also give some biasedness. So I would recommend my first method to generate random numbers within a specific range.
In both methods, your console will show the result (press F12 in Chrome to open the console).
function getRandomInt(lower, upper)
{
//to create an even sample distribution
return Math.floor(lower + (Math.random() * (upper - lower + 1)));
//to produce an uneven sample distribution
//return Math.round(lower + (Math.random() * (upper - lower)));
//to exclude the max value from the possible values
//return Math.floor(lower + (Math.random() * (upper - lower)));
}
To test this function, and variations of this function, save the below HTML/JavaScript to a file and open with a browser. The code will produce a graph showing the distribution of one million function calls. The code will also record the edge cases, so if the the function produces a value greater than the max, or less than the min, you.will.know.about.it.
<html>
<head>
<script type="text/javascript">
function getRandomInt(lower, upper)
{
//to create an even sample distribution
return Math.floor(lower + (Math.random() * (upper - lower + 1)));
//to produce an uneven sample distribution
//return Math.round(lower + (Math.random() * (upper - lower)));
//to exclude the max value from the possible values
//return Math.floor(lower + (Math.random() * (upper - lower)));
}
var min = -5;
var max = 5;
var array = new Array();
for(var i = 0; i <= (max - min) + 2; i++) {
array.push(0);
}
for(var i = 0; i < 1000000; i++) {
var random = getRandomInt(min, max);
array[random - min + 1]++;
}
var maxSample = 0;
for(var i = 0; i < max - min; i++) {
maxSample = Math.max(maxSample, array[i]);
}
//create a bar graph to show the sample distribution
var maxHeight = 500;
for(var i = 0; i <= (max - min) + 2; i++) {
var sampleHeight = (array[i]/maxSample) * maxHeight;
document.write('<span style="display:inline-block;color:'+(sampleHeight == 0 ? 'black' : 'white')+';background-color:black;height:'+sampleHeight+'px"> [' + (i + min - 1) + ']: '+array[i]+'</span> ');
}
document.write('<hr/>');
</script>
</head>
<body>
</body>
</html>
For a random integer with a range, try:
function random(minimum, maximum) {
var bool = true;
while (bool) {
var number = (Math.floor(Math.random() * maximum + 1) + minimum);
if (number > 20) {
bool = true;
} else {
bool = false;
}
}
return number;
}
Here is a function that generates a random number between min and max, both inclusive.
const randomInt = (max, min) => Math.round(Math.random() * (max - min)) + min;
To get a random number say between 1 and 6, first do:
0.5 + (Math.random() * ((6 - 1) + 1))
This multiplies a random number by 6 and then adds 0.5 to it. Next round the number to a positive integer by doing:
Math.round(0.5 + (Math.random() * ((6 - 1) + 1))
This round the number to the nearest whole number.
Or to make it more understandable do this:
var value = 0.5 + (Math.random() * ((6 - 1) + 1))
var roll = Math.round(value);
return roll;
In general, the code for doing this using variables is:
var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
var roll = Math.round(value);
return roll;
The reason for taking away 0.5 from the minimum value is because using the minimum value alone would allow you to get an integer that was one more than your maximum value. By taking away 0.5 from the minimum value you are essentially preventing the maximum value from being rounded up.
Using the following code, you can generate an array of random numbers, without repeating, in a given range.
function genRandomNumber(how_many_numbers, min, max) {
// Parameters
//
// how_many_numbers: How many numbers you want to
// generate. For example, it is 5.
//
// min (inclusive): Minimum/low value of a range. It
// must be any positive integer, but
// less than max. I.e., 4.
//
// max (inclusive): Maximum value of a range. it must
// be any positive integer. I.e., 50
//
// Return type: array
var random_number = [];
for (var i = 0; i < how_many_numbers; i++) {
var gen_num = parseInt((Math.random() * (max-min+1)) + min);
do {
var is_exist = random_number.indexOf(gen_num);
if (is_exist >= 0) {
gen_num = parseInt((Math.random() * (max-min+1)) + min);
}
else {
random_number.push(gen_num);
is_exist = -2;
}
}
while (is_exist > -1);
}
document.getElementById('box').innerHTML = random_number;
}
Random whole number between lowest and highest:
function randomRange(low, high) {
var range = (high-low);
var random = Math.floor(Math.random()*range);
if (random === 0) {
random += 1;
}
return low + random;
}
It is not the most elegant solution, but something quick.
I found this simple method on W3Schools:
Math.floor((Math.random() * max) + min);
Math.random() is fast and suitable for many purposes, but it's not appropriate if you need cryptographically-secure values (it's not secure), or if you need integers from a completely uniform unbiased distribution (the multiplication approach used in others answers produces certain values slightly more often than others).
In such cases, we can use crypto.getRandomValues() to generate secure integers, and reject any generated values that we can't map uniformly into the target range. This will be slower, but it shouldn't be significant unless you're generating extremely large numbers of values.
To clarify the biased distribution concern, consider the case where we want to generate a value between 1 and 5, but we have a random number generator that produces values between 1 and 16 (a 4-bit value). We want to have the same number of generated values mapping to each output value, but 16 does not evenly divide by 5: it leaves a remainder of 1. So we need to reject 1 of the possible generated values, and only continue when we get one of the 15 lesser values that can be uniformly mapped into our target range. Our behaviour could look like this pseudocode:
Generate a 4-bit integer in the range 1-16.
If we generated 1, 6, or 11 then output 1.
If we generated 2, 7, or 12 then output 2.
If we generated 3, 8, or 13 then output 3.
If we generated 4, 9, or 14 then output 4.
If we generated 5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.
The following code uses similar logic, but generates a 32-bit integer instead, because that's the largest common integer size that can be represented by JavaScript's standard number type. (This could be modified to use BigInts if you need a larger range.) Regardless of the chosen range, the fraction of generated values that are rejected will always be less than 0.5, so the expected number of rejections will always be less than 1.0 and usually close to 0.0; you don't need to worry about it looping forever.
const randomInteger = (min, max) => {
const range = max - min;
const maxGeneratedValue = 0xFFFFFFFF;
const possibleResultValues = range + 1;
const possibleGeneratedValues = maxGeneratedValue + 1;
const remainder = possibleGeneratedValues % possibleResultValues;
const maxUnbiased = maxGeneratedValue - remainder;
if (!Number.isInteger(min) || !Number.isInteger(max) ||
max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
throw new Error('Arguments must be safe integers.');
} else if (range > maxGeneratedValue) {
throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
} else if (max < min) {
throw new Error(`max (${max}) must be >= min (${min}).`);
} else if (min === max) {
return min;
}
let generated;
do {
generated = crypto.getRandomValues(new Uint32Array(1))[0];
} while (generated > maxUnbiased);
return min + (generated % possibleResultValues);
};
console.log(randomInteger(-8, 8)); // -2
console.log(randomInteger(0, 0)); // 0
console.log(randomInteger(0, 0xFFFFFFFF)); // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]
Here is an example of a JavaScript function that can generate a random number of any specified length without using Math.random():
function genRandom(length)
{
const t1 = new Date().getMilliseconds();
var min = "1", max = "9";
var result;
var numLength = length;
if (numLength != 0)
{
for (var i = 1; i < numLength; i++)
{
min = min.toString() + "0";
max = max.toString() + "9";
}
}
else
{
min = 0;
max = 0;
return;
}
for (var i = min; i <= max; i++)
{
// Empty Loop
}
const t2 = new Date().getMilliseconds();
console.log(t2);
result = ((max - min)*t1)/t2;
console.log(result);
return result;
}
Use:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script>
/*
Assuming that window.crypto.getRandomValues
is available, the real range would be from
0 to 1,998 instead of 0 to 2,000.
See the JavaScript documentation
for an explanation:
https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
*/
var array = new Uint8Array(2);
window.crypto.getRandomValues(array);
console.log(array[0] + array[1]);
</script>
</body>
</html>
Uint8Array creates an array filled with a number up to three digits which would be a maximum of 999. This code is very short.
This is my take on a random number in a range, as in I wanted to get a random number within a range of base to exponent. E.g., base = 10, exponent = 2, gives a random number from 0 to 100, ideally, and so on.
If it helps using it, here it is:
// Get random number within provided base + exponent
// By Goran Biljetina --> 2012
function isEmpty(value) {
return (typeof value === "undefined" || value === null);
}
var numSeq = new Array();
function add(num, seq) {
var toAdd = new Object();
toAdd.num = num;
toAdd.seq = seq;
numSeq[numSeq.length] = toAdd;
}
function fillNumSeq (num, seq) {
var n;
for(i=0; i<=seq; i++) {
n = Math.pow(num, i);
add(n, i);
}
}
function getRandNum(base, exp) {
if (isEmpty(base)) {
console.log("Specify value for base parameter");
}
if (isEmpty(exp)) {
console.log("Specify value for exponent parameter");
}
fillNumSeq(base, exp);
var emax;
var eseq;
var nseed;
var nspan;
emax = (numSeq.length);
eseq = Math.floor(Math.random()*emax) + 1;
nseed = numSeq[eseq].num;
nspan = Math.floor((Math.random())*(Math.random()*nseed)) + 1;
return Math.floor(Math.random()*nspan) + 1;
}
console.log(getRandNum(10, 20), numSeq);
//Testing:
//getRandNum(-10, 20);
//console.log(getRandNum(-10, 20), numSeq);
//console.log(numSeq);
This I guess, is the most simplified of all the contributions.
maxNum = 8,
minNum = 4
console.log(Math.floor(Math.random() * (maxNum - minNum) + minNum))
console.log(Math.floor(Math.random() * (8 - 4) + 4))
This will log random numbers between 4 and 8 into the console, 4 and 8 inclusive.
Ionuț G. Stan wrote a great answer, but it was a bit too complex for me to grasp. So, I found an even simpler explanation of the same concepts at Math.floor( Math.random () * (max - min + 1)) + min) Explanation by Jason Anello.
Note: The only important thing you should know before reading Jason's explanation is a definition of "truncate". He uses that term when describing Math.floor(). Oxford dictionary defines "truncate" as:
Shorten (something) by cutting off the top or end.
A function called randUpTo that accepts a number and returns a random whole number between 0 and that number:
var randUpTo = function(num) {
return Math.floor(Math.random() * (num - 1) + 0);
};
A function called randBetween that accepts two numbers representing a range and returns a random whole number between those two numbers:
var randBetween = function (min, max) {
return Math.floor(Math.random() * (max - min - 1)) + min;
};
A function called randFromTill that accepts two numbers representing a range and returns a random number between min (inclusive) and max (exclusive)
var randFromTill = function (min, max) {
return Math.random() * (max - min) + min;
};
A function called randFromTo that accepts two numbers representing a range and returns a random integer between min (inclusive) and max (inclusive):
var randFromTo = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
You can you this code snippet,
let randomNumber = function(first, second) {
let number = Math.floor(Math.random()*Math.floor(second));
while(number < first) {
number = Math.floor(Math.random()*Math.floor(second));
}
return number;
}
I would like get a random number in a range excluding one number (e.g. from 1 to 1000 exclude 577). I searched for a solution, but never solved my issue.
I want something like:
Math.floor((Math.random() * 1000) + 1).exclude(577);
I would like to avoid for loops creating an array as much as possible, because the length is always different (sometimes 1 to 10000, sometimes 685 to 888555444, etc), and the process of generating it could take too much time.
I already tried:
Javascript - Generating Random numbers in a Range, excluding certain numbers
How can I generate a random number within a range but exclude some?
How could I achieve this?
The fastest way to obtain a random integer number in a certain range [a, b], excluding one value c, is to generate it between a and b-1, and then increment it by one if it's higher than or equal to c.
Here's a working function:
function randomExcluded(min, max, excluded) {
var n = Math.floor(Math.random() * (max-min) + min);
if (n >= excluded) n++;
return n;
}
This solution only has a complexity of O(1).
One possibility is not to add 1, and if that number comes out, you assign the last possible value.
For example:
var result = Math.floor((Math.random() * 100000));
if(result==577) result = 100000;
In this way, you will not need to re-launch the random method, but is repeated. And meets the objective of being a random.
As #ebyrob suggested, you can create a function that makes a mapping from a smaller set to the larger set with excluded values by adding 1 for each value that it is larger than or equal to:
// min - integer
// max - integer
// exclusions - array of integers
// - must contain unique integers between min & max
function RandomNumber(min, max, exclusions) {
// As #Fabian pointed out, sorting is necessary
// We use concat to avoid mutating the original array
// See: http://stackoverflow.com/questions/9592740/how-can-you-sort-an-array-without-mutating-the-original-array
var exclusionsSorted = exclusions.concat().sort(function(a, b) {
return a - b
});
var logicalMax = max - exclusionsSorted.length;
var randomNumber = Math.floor(Math.random() * (logicalMax - min + 1)) + min;
for(var i = 0; i < exclusionsSorted.length; i++) {
if (randomNumber >= exclusionsSorted[i]) {
randomNumber++;
}
}
return randomNumber;
}
Example Fiddle
Also, I think #JesusCuesta's answer provides a simpler mapping and is better.
Update: My original answer had many issues with it.
To expand on #Jesus Cuesta's answer:
function RandomNumber(min, max, exclusions) {
var hash = new Object();
for(var i = 0; i < exclusions.length; ++i ) { // TODO: run only once as setup
hash[exclusions[i]] = i + max - exclusions.length;
}
var randomNumber = Math.floor((Math.random() * (max - min - exclusions.length)) + min);
if (hash.hasOwnProperty(randomNumber)) {
randomNumber = hash[randomNumber];
}
return randomNumber;
}
Note: This only works if max - exclusions.length > maximum exclusion. So close.
You could just continue generating the number until you find it suits your needs:
function randomExcluded(start, end, excluded) {
var n = excluded
while (n == excluded)
n = Math.floor((Math.random() * (end-start+1) + start));
return n;
}
myRandom = randomExcluded(1, 10000, 577);
By the way this is not the best solution at all, look at my other answer for a better one!
Generate a random number and if it matches the excluded number then add another random number(-20 to 20)
var max = 99999, min = 1, exclude = 577;
var num = Math.floor(Math.random() * (max - min)) + min ;
while(num == exclude || num > max || num < min ) {
var rand = Math.random() > .5 ? -20 : 20 ;
num += Math.floor((Math.random() * (rand));
}
import random
def rng_generator():
a = random.randint(0, 100)
if a == 577:
rng_generator()
else:
print(a)
#main()
rng_generator()
Exclude the number from calculations:
function toggleRand() {
// demonstration code only.
// this algorithm does NOT produce random numbers.
// return `0` - `576` , `578` - `n`
return [Math.floor((Math.random() * 576) + 1)
,Math.floor(Math.random() * (100000 - 578) + 1)
]
// select "random" index
[Math.random() > .5 ? 0 : 1];
}
console.log(toggleRand());
Alternatively, use String.prototype.replace() with RegExp /^(577)$/ to match number that should be excluded from result; replace with another random number in range [0-99] utilizing new Date().getTime(), isNaN() and String.prototype.slice()
console.log(
+String(Math.floor(Math.random()*(578 - 575) + 575))
.replace(/^(577)$/,String(isNaN("$1")&&new Date().getTime()).slice(-2))
);
Could also use String.prototype.match() to filter results:
console.log(
+String(Math.floor(Math.random()*10))
.replace(/^(5)$/,String(isNaN("$1")&&new Date().getTime()).match(/[^5]/g).slice(-1)[0])
);