JavaScript code explanation for this sample? - javascript

Hello everyone! I have completed a couple of brief courses in JavaScript, and I have now moved on to Heads Up: JavaScript, which has been a lot of fun and is helping to cement my learning. I did run into something I didn't understand, though. In the following piece of code, I understand what the program generally does when it executes, but in attempting to trace each step of execution, I realized that I am confounded by the "What/Why/How" of a particular segment. Here's the code for the sample program I'm looking at:
function makePhrases() {
var words1 = ["24/7", "multi-tier", "30,000 foot", "B-to-B", "win-win"];
var words2 = ["empowered", "value-added", "oriented", "focused", "aligned"];
var words3 = ["process", "solution", "tipping-point", "strategy", "vision"];
var rand1 = Math.floor(Math.random() * words1.length);
var rand2 = Math.floor(Math.random() * words2.length);
var rand3 = Math.floor(Math.random() * words3.length);
var phrase = words1[rand1] + " " + words2[rand2] + " " + words3[rand3];
alert(phrase);
}
makePhrases();
This is the segment that has been confusing for me:
var rand1 = Math.floor(Math.random() * words1.length);
var rand2 = Math.floor(Math.random() * words2.length);
var rand3 = Math.floor(Math.random() * words3.length);
I get that it's the part of the code that randomizes which item from each array is chosen to form the new "random phrase", but I don't understand how it's doing so. I also hadn't known previously that Math.random or Math.floor could be applied to strings (must be because they're in an array, which is essentially a number?), or the how/why of using Math.random or Math.floor with strings.
Additionally, why do we need to use .length with this incarnation? What does it do? I appreciate your wisdom here, and taking the time to help someone who's new to coding, and still has so much to learn!

Let's look at the code:
var rand1 = Math.floor(Math.random() * words1.length);
Math.random() returns a number between 0 and 0.999999...
words1 is the list of words to choose from.
words1.length is the size of the list, the number of items, 5 in this case.
Math.random() * words1.length returns a number between 0 and 4.99999...
Finally use Math.floor() to get a whole number between 0 and 4.
This number is then used as an index in words1, so words1[rand1].
So the Math operations are never used on a string, fetching the string in only the last step.

All that's happening is Math.random() is being used as a multiplier against the number of elements in the respective arrays (the '.length' property) to create an index value. It isn't being applied to a string; just as part of an expression to determine an index into a string array.

You want to pick a random element from an array. So you need an index, in other words a random number from 0 to 4 (because your length is 5). Math.random will give you a random number between 0 and 1 (exclusive of 1). So to turn that into a random number between 0 and 4 you need to multiple by the length of 5.
Then, since we need an integer, not a floating point number, we use Math.floor to truncate it to a integer.

Math.random() //Return a random number between 0-1
words1.length() //Return the length of the array
Math.floor() //Return the closest integer less than or equal to a given number.
Now the expressions:
(Math.random() * words1.length)
Will return a random number between 0 and the length of the array. Could be a float, like 3,4 for example:
Math.floor(Math.random() * words1.length)
Will return an integer number between 0 and the length of the string, so you can use it now as the string (behaving like an array) indexer.
Note: Note that the random number is between 0 (inclusive) and 1 (exclusive), that's why is secure to use Math.floor(), to avoid an exception, and that's why is not used Math.ceiling.

Related

var damage = Math.max(Math.floor(Math.random() * max)+1, min) what is the meaning first 'Math.max' and last ',min' here

var damage = Math.max(Math.floor(Math.random() * max)+1, min);
What is the meaning first Math.max and last ,min here. Please explain the whole line.
Math.max is a function that, when passed a variable amount of numbers, returns the largest number:
console.log(Math.max(1, 2, 3));
min in your code is the minimum number that damage can be - so it works out as (pseudocode):
set damage to the maximum number out of:
A random number between 0 and 1, multiplied by max, rounded down,
or min;
Math is a build in object in javascript that has method and properties & here [Math.max][2] is use to find the largest of numbers. Math.floor & Math.random are also available methods
I have broken down the code into multiple lines, for ease of understanding
function findMax(max, min) {
let findRandom = Math.random() * max; // generate a random number
// if it is a decimal number get the previous whole number
let findLower = Math.floor(findRandom);
// add one with the generated whole number
let addOne = findLower + 1;
// find the maximum between two numbers, one is generated & another is
// supplied as argument
let damage = Math.max(addOne, min)
return damage;
}
console.log(findMax(4, 1))
If you look up Math.random at MDN:
The Math.random() function returns a floating-point, pseudo-random
number in the range 0–1 (inclusive of 0, but not 1) with approximately
uniform distribution over that range — which you can then scale to
your desired range.
So here, the range is max and you are taking the Math.floor of the expression Math.random() * max and then adding 1 to it.
Math.floor will round the number produced to the largest integer less than or equal to a given result. So if the Math.random() * max results in say 5.95 the Math.floor will make the resulting number 5.
Then at the end we are finding the maximum of the resulting number of the previous step and the min variable and assigning the result to the damage variable.

JS - How can I generate a long random number?

I know that I need to use Math.random() for making random numbers, but today I tried to make a random number between 1 and 9999...(9 repeated 19 times) and my output always ends in 3-5 zeroes. How can I generate more detailed random numbers?
What I've done:
const foo = Math.floor(Math.random() * parseInt("9".repeat(19)));
Also, I'm pretty sure I know how to do this, but if anyone can tell me, how do I pad zeroes to get to a certain digit count?
(ex. pad(15,4) becomes 0015 because the you need 2 more digits to make it 4 digits long)
The best idea is probably to just use a string of random integers (solves padding too):
let foo = '';
for(i=0; i<19; ++i) foo += Math.floor(Math.random() * 10);
alert(foo);
You need to use numbers encoded as strings. A loop like this:
var desiredMaxLength = 19
var randomNumber = '';
for (var i = 0; i < desiredMaxLength; i++) {
randomNumber += Math.floor(Math.random() * 10);
}
Arthimetic for numbers represented as strings can be donw with the strint library found at https://github.com/rauschma/strint.
You are running into Number.MAX_SAFE_INTEGER. The largest exact integral value is 2^53-1, or 9007199254740991.

javascript get random number: lower probability to get higher number in the interval

Ok, so I have very big array of numbers in javascript:
[1, 1.01, 1.02, 1.03, ..., 1.99, 2, ..., 9.98, 9.99, ..., 299.99, 300]
And what I need is to get one of them using random segment. So basically I need random number but the catch is that I need to get random using the lottery style. So the chance to get "1" will be 30 000 (very hight) and the chance to get 1.01 will be 29 999. But the chance to get 300 will be very low according of all numbers in this array.
I hope you will understand the problem and will help me to solve this. As I have mentioned before, this have to be made 100% randomly and I have no idea how to make it..
The solution I had so far:
I was trying to expanse the array by adding multiple same numbers and lower the count of it by each step. So I have added 30000 units of 1 and 29999 units of 1.01 ... and 2 units of 299.99 and one unit of 300. But the array got very large and I came here to find better solution.
Also I have found this: https://stackoverflow.com/a/13758064/5786106
and it seems to be the answer to me but I don't know how to use it with the decimal system (0.01, 0.02, ... 0.99)
var num = Math.pow(Math.floor(Math.random()*10), 2);
One solution would be to make the very large array you propose, but to make it imaginary, without ever constructing that object in code.
How long will the imaginary array be? Well your array has (300 - 1) * 100 + 1 = 29,901 elements in it. Then there are (29,901 + 1) * (29,901 / 2) = 447,049,851 elements in the imaginary array. So the first step is to generate a random integer between 0 and 447,049,850:
var imaginaryIndex = Math.floor(Math.random() * 447049851);
The next step is to determine which real index in your original array corresponds to the imaginaryIndex in the imaginary array.
var indexFromEnd = 0;
while((indexFromEnd + 2) * ((indexFromEnd + 1) / 2) < imaginaryIndex)
indexFromEnd++;
Finally, you need to calculate the value of the element in your array based on where it is in your array:
return 300 - (indexFromEnd * 0.01);
Now let's clean that up and put it in a nice, reusable function:
function triangularWeightedRandomSelect(myArray){
var imaginaryIndex =
Math.floor(Math.random() * (myArray.length + 1) * myArray.length / 2);
var indexFromEnd = 0;
while((indexFromEnd + 2) * ((indexFromEnd + 1) / 2) < imaginaryIndex)
indexFromEnd++;
return myArray[myArray.length - 1 - indexFromEnd];
}

when generating normally-distributed random values, what is the most efficient way to define the range?

FYI: random == pseudo-random
A. when generating uniformly-random numbers, I can specify a range, i.e.:
(Math.random()-Math.random())*10+5
//generates numbers between -5 and 15
B. generating a set of random values with a version of Gaussian-esque normal randomness:
//pass in the mean and standard deviation
function randomNorm(mean, stdev) {
return Math.round((Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1))*stdev+mean);
}
//using the following values:
{
mean:400,
standard_deviation:1
//results in a range of 397-403, or +-range of 3
},
{
mean:400,
standard_deviation:10
//results in a range of 372-429, or +-range of 30
},
{
mean:400,
standard_deviation:25
//results in a range of 326-471, or +-range of 75
}
each one gives me a range of approximately standard_deviation*(+-3) (assuming I left the program running longer).
C. I can calculate this range as follows:
assuming I want a range from 300-500, so var total_range = 200;
my mean is 400, my +-range is total_range/2 (var r = 100)
so standard_deviation would be r/3 or in this case 33.333.
This seems to be working, but I have no idea what I'm doing with math so I feel like an idiot, this solution feels kludgy and not totally accurate.
My question:
is there some formula that I'm dancing around that can help me here? my requirements are as follows:
must be able to define a range of numbers accurately.
must be done in JavaScript, as efficiently as possible.
I think maybe I'm close but it's not quite there.
Subtracting two random numbers doesn't give you a normal distribution, it will give you numbers that decline linearly on both sides of zero. See the red diagram in this fiddle:
http://jsfiddle.net/Guffa/tvt5K/
To get a good approximation of normal distribution, add six random numbers together. See the green diagram in the fiddle.
So, to get normally distributed random numbers, use:
((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3
This method is based on the central limit theorem, outlined as the second method here: http://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution
I wanted to have gaussian random numbers between 0 and 1, and after many tests (thanks to #Guffa answer too) I found this to be the best:
function gaussianRand() {
var rand = 0;
for (var i = 0; i < 6; i += 1) {
rand += Math.random();
}
return rand / 6;
}
And as a bonus:
function gaussianRandom(start, end) {
return Math.floor(start + gaussianRand() * (end - start + 1));
}

javascript random numbers make the chance bigger to get some values

i've made some kind of encode function that uses an array with 62 characters (a-z,A-Z,0-9)
then i use a random number to access one of these.
but if i use it, it returns way to much letters and i want as much letters as numbers (which is also logical since the chance on a number is 10/62 versus 50/62)
could someone tell me some function that generates a random number but that has a higher chance to get a value between 52-62 then a value below 52.
This gives you a 50/50 chance of getting a digit:
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var digits = "0123456789";
function getRandomChar() {
var r = Math.random();
return r < 0.5 ? letters.charAt(Math.floor(r*letters.length*2)) : digits.charAt(Math.floor((r-0.5)*digits.length*2));
}
If you want to get random value between for example 0..100 but with a higher chance to happen in 50..60 you should add a second random function into equation:
var rnd = Math.round(Math.random()*( 100 - 50 ) + Math.round(Math.random()*10));
In this case first random number is generated to be between 0 and 50, then it get's a chance to be higher until 60
In your case for 52-62 it should be like this:
var rnd = Math.round(Math.random()*( 52 ) + Math.round(Math.random()*10));
First choose between 0 and 1 (heads or tails), if it's one, use a separate function that only returns numbers. Otherwise return a letter with a separate function that only returns letters.
function getRandomIndex(){
// flip a coin... 50% chance the if occurs, 50% chance the else occurs
if(Math.floor(Math.random() * 2) == 0){
// return the number random function, values 52 and up
return Math.floor(Math.random() * 10) + 52;
}
else{
// return the character random function, values 0 to 51
return Math.floor(Math.random() * 52);
}
}

Categories