VERSIÓN EN ESPAÑOL

Source
El último post de programación lo hice explicando la función de aleatoriedad, ahora vamos a agregarle un poco más de complejidad y haremos lo mismo, pero delimitaremos un rango para dicha funcionalidad, es decir, que podamos pedir un número entre un mínimo y máximo específico, por ejemplo, entre 1 y 3. Para hacer esto, lo primero que tenemos que tener en cuenta es lo que entendemos por rango, y esto no es más que la cantidad de números que hay entre dos enteremos específicos. Así tenemos que en el ejemplo anterior este rango es de 2. Luego lo que procede es multiplicar Math.random por el rango deseado.
En código esto sería así:
Math.random()*(max-min)
Aquí ya tenemos la primera dificultad, ya que - siguiendo los número ya señalados como ejemplo.
- El mínimo valor que obtendremos será 0, resultado de la multiplicación del mínimo número random (0) por el máximo número del rango (2), Pues, 0*2 = 0;
- El máximo valor que obtendremos será 1.9999, resultado de la multiplicación del máximo número random (0.99999) por el máximo número del rango (2), Pues, 0.99999*2 = 1.99998;
Para corregir esto tenemos que hacer dos cosas (la última si usamos el método Math.floor que aquí demostraremos por qué es mejor que Math.round) Lo primero es sumar el número inferior del rango por el resultado de la operación, así:
(Math.random()*(max-min)) + min
Es de resaltar que aquí lo importante es sumar el número inferior del rango deseado, ya que si por ejemplo queremos un número aleatorio entre 54 y 57 cuyo rango es 3 (porque de 54 a 57 hay un intervalo de 3 números) no vamos a sumar un 1 sino el 54. De esta manera el mínimo sería 54 (porque 0 + 54 = 54) y el máximo 56.99999 (porque 2.99999 + 54 = 56.99999).
En este último caso, nos conseguimos con otra dificultad si usamos el método Math.floor, pues, nunca daremos con el máximo, no así con el método Math.round, que eventualmente me dará un número mayor a 56.50, que automáticamente se redondeará hasta 57. Así que si seguimos este último caso, ya aquí pudiésemos terminar la función. De esta manera:
function rangoRound (min, max) {
return Math.round(Math.random()* (max-min) + min)
}
Ahora bien, como queremos demostrar por qué es mejor usar Math.floor veamos cuál es la dificultad respecto a este método aplicado al caso que traemos en cuestión.
- El problema está en que aunque ya tenemos el mínimo del rango bien definido no así con el máximo. En el último ejemplo tenemos que el mínimo sería 54, lo cual nos sirve, pero siendo el máximo 56.999, esto si no nos funciona, ya que al eliminar los decimales (lo que hace el método que queremos utilizar) el máximo no será el que buscamos (57) sino un número menos (56). ¿Cuál sería la solución?
He aquí la segunda cosa que debemos hacer y es sumar un 1 al rango. De esta manera, el mínimo seguirá siendo como lo queremos 54 y el máximo podrá llegar hasta 57.99999 (porque 3.99999 + 54 = 57.99999). De esta manera, en este caso la función quedaría así:
function rangoFloor (min, max) {
return Math.floor(Math.random()* (max-min+1) + min)
}
Bonus
Vamos ahora a demostrar porque sería mejor usar el método Math.floor que el Math.round. Lo haremos estudiando las posibilidades que salgan los números dentro del rango de la manera más equitativa posible. El método que lo logre o se acerque más, este será el mejor. Para realizar esto vamos a contabilizar cuántas veces sale los números en el rango comprendido de 1-10. Para ello crearemos un array con el índice de 0 a 10 con el valor a 0, para luego hacer unas simulaciones con el ciclo for para comparar resultados. Esto quedaría así:
function rangoRound(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
//array para llevar la cuenta de los valores
let valueCount = [];
// inicializo el array a cero en todos sus valores comenzando desde el índice 0 (que no se puede obviar) a 10.
for (let index = 0; index < 11; index++) {
valueCount.push(0);
}
//corremos simulaciones
for (let i = 0; i <= 10000; i++) {
let simulacionesRangoRound = rangoRound(1, 10);
valueCount[simulacionesRangoRound]++;
}
console.log(valueCount);
- En esta prueba podemos comprobar que los números extremos del rango (1 y 10) tienen el 50 % de posibilidad de salir en comparación con los demás (del 2 al 9). Lo cual si aplicamos la misma fórmula, pero con el método Math.floor notaremos que es más equitativo, todos los números tendrán un porcentaje de aparición semejante. Por eso, es que este último método es mejor, así como lo dejamos reflejado abajo.
👇 👇 👇
function rangoFloor(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
//array para llevar la cuenta de los valores
let valueCount = [];
// inicializo el array a cero en todos sus valores comenzando desde el índice 0 (que no se puede obviar) a 10.
for (let index = 0; index < 11; index++) {
valueCount.push(0);
}
//corremos simulaciones
for (let i = 0; i <= 10000; i++) {
let simulacionesRangoFloor = rangoFloor(1, 10);
valueCount[simulacionesRangoFloor]++;
}
console.log(valueCount);

ENGLISH VERSION
JS Programming - Randomization with Rank plus a Bonus

Source
The last post of programming I did it explaining the randomness function, now we are going to add a little more complexity and we will do the same, but we will delimit a range for this functionality, that is to say, that we can ask for a number between a minimum and maximum specific, for example, between 1 and 3. To do this, the first thing we have to take into account is what we mean by range, and this is nothing more than the amount of numbers between two specific integers. So we have that in the previous example this range is 2. Then what proceeds is to multiply Math.random by the desired range. In code this would be like this:
Math.random()*(max-min)
Here we already have the first difficulty, since - following the numbers already indicated as an example.
- The minimum value that we will obtain will be 0, result of the multiplication of the minimum random number (0) by the maximum number of the range (2), So, 02 = 0; - The maximum value that we will obtain will be 1.9999, result of the multiplication of the maximum random number (0.99999) by the maximum number of the range (2), So, 0.999992 = 1.99998;
To correct this we have to do two things (the last one if we use the method Math.floor that here we will demonstrate why it is better than Math.round) The first is to add the lower number of the range by the result of the operation, like this:
(Math.random()*(max-min)) + min
It is to emphasize that here the important thing is to add the inferior number of the wished range, since if for example we want a random number between 54 and 57 whose range is 3 (because from 54 to 57 there is an interval of 3 numbers) we are not going to add a 1 but the 54. In this way the minimum would be 54 (because 0 + 54 = 54) and the maximum 56.99999 (because 2.99999 + 54 = 56.99999).
In this last case, we get another difficulty if we use the method Math.floor, because, we will never find the maximum, not so with the method Math.round, that eventually will give me a number greater than 56.50, that automatically will be rounded up to 57. So if we follow the latter case, already here we could finish the function. In this way:
function rangoRound (min, max) {
return Math.round(Math.random()* (max-min) + min)
}
Now, as we want to demonstrate why it is better to use Math.floor let's see what is the difficulty with respect to this method applied to the case that we bring in question.
- The problem is that although we already have the minimum of the range well defined, not so with the maximum. In the last example we have that the minimum would be 54, which works for us, but being the maximum 56,999, this does not work for us, since when eliminating the decimals (what does the method that we want to use) the maximum will not be the one that we look for (57) but a number less (56). What would be the solution?
Here is the second thing we must do and that is to add a 1 to the range. In this way, the minimum will still be as we want it 54 and the maximum can go up to 57.99999 (because 3.99999 + 54 = 57.99999). Thus, in this case the function would look like this:
function rangoFloor (min, max) {
return Math.floor(Math.random()* (max-min+1) + min)
}
Bonus
Let's now demonstrate why it would be better to use the Math.floor method than the Math.round method. We will do this by studying the chances that the numbers in the range will come out as equally as possible. The method that achieves this, or comes closest, will be the best. To do this we are going to count how many times the numbers in the range 1-10 come out. To do this we will create an array with the index from 0 to 10 with the value at 0, and then do some simulations with the for cycle to compare results. This would look like this:
function rangoRound(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
//array para llevar la cuenta de los valores
let valueCount = [];
// inicializo el array a cero en todos sus valores comenzando desde el índice 0 (que no se puede obviar) a 10.
for (let index = 0; index < 11; index++) {
valueCount.push(0);
}
//corremos simulaciones
for (let i = 0; i <= 10000; i++) {
let simulacionesRangoRound = rangoRound(1, 10);
valueCount[simulacionesRangoRound]++;
}
console.log(valueCount);
- In this test we can verify that the extreme numbers of the range (1 and 10) have 50% of possibility to appear in comparison with the others (from 2 to 9). Which if we apply the same formula, but with the method Math.floor we will notice that it is more equitable, all the numbers will have a similar percentage of appearance. That is why the latter method is better, as we have shown below.👇 👇 👇
function rangoFloor(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
//array para llevar la cuenta de los valores
let valueCount = [];
// inicializo el array a cero en todos sus valores comenzando desde el índice 0 (que no se puede obviar) a 10.
for (let index = 0; index < 11; index++) {
valueCount.push(0);
}
//corremos simulaciones
for (let i = 0; i <= 10000; i++) {
let simulacionesRangoFloor = rangoFloor(1, 10);
valueCount[simulacionesRangoFloor]++;
}
console.log(valueCount);


