Ir al contenido principal

Destacados

Crear String usando Template Literals

Los templates literals , simplifican una concatenación de cadenas. Su sintaxis:   ´ cadena ${ expresión } ´ Ejemplo: Ejercicio freeCodeCamp Utilice la sintaxis template literal para crear una matriz de lista de elementos (li). El texto de cada elemento de la lista debe ser uno de los elementos de la matriz failure que es una propiedad del objeto result . Además, debe tener un atributo class con el valor "text-warning" . La función makeList debería devolver la matriz de cadenas de elementos de la lista. Utilice cualquier tipo de bucle para obtener la salida deseada (que se muestra a continuación). Código a modificar Solución La constante failuresList llama a la función makeList que tiene como argumento al objeto result y su propiedad failure que es una matriz de tres elementos.  El argumento arr sustituye a result.failure en la función. Se crea una nueva matriz failureItems para guardar los elementos que se leerán del objeto result.failure. Se usa el bucle for ...

Divisores comunes de dos números dados en Javascript



Analizamos el enunciado.

El programa tomará dos números cualquiera que ingrese el usuario. Estos números deben ser diferentes a 0, también debe bloquear la entrada de caracteres especiales y letras, porque no son divisibles por un número. Para conocer los números comunes de los dos números dados, primero se debe conocer cuáles son sus divisores.

Con este ejercicio pondremos en práctica:

  • Vectores unidimensionales
  • Método push()
  • Number.parseInt()
  • isNaN()
  • prompt()
  • Operadores lógicos &&
  • Bucle For
  • Condicional If
  • Operador numérico %


Para la práctica creamos un archivo HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
     Escribe el código Javascript aquí
    </script>
  </body>
</html>

1.- Bloque de entrada de data e inicialización de las variables.

/*--------------------------------------------------------
      Bloque ingreso de datos e inicialización de variables 
   ---------------------------------------------------------*/

 let num1 = Number.parseInt(prompt("Introduzca el 1er número"));
 let num2 = Number.parseInt(prompt("Introduzca el 2do número"));
 let vector1 = [];
 let vector2 = [];
 let vector3 = [];

Las variables se declaran con "let" según la última actualización de ECMAscript6.

El método prompt(), muestra un cuadro de diálogo en la pantalla solicitando se ingresen los datos requeridos. 

Prompt() interpreta estos datos como una cadena.

Ventana método prompt()

El método Number.parseInt() convierte la cadena en dígitos numéricos y los números fraccionarios en números enteros. 

Esto ayuda a validar que los datos que se reciban sean los correctos para la ejecución del programa.  

Si el usuario escribe 2.5 como dato de entrada, el programa solo tomará su parte entera, es decir, el número 2.

Las variables que se comportarán como vectores se inicializan con corchetes vacíos.

Javascript permite que podamos resumir en una línea la declaración de la variable e iniciarla con los métodos Number.parseInt  y prompt

let num1 = Number.parseInt(prompt("Introduzca el 1er número"));

También necesitamos guardar en una sola variable, todos los números que son divisibles a cada uno. Los vectores son útiles para ello.

  • vector1 para almacenar los divisores de num1
  • vector2 para almacenar los divisores de num2
  • vector3 para almacenar los divisores comunes a num1 y num2

Todas las variables se declaran con “let” y se inicializan con corchetes vacíos.


      let vector1 = [];
      let vector2 = [];
      let vector3 = [];

Ya tenemos el primer bloque del programa construído. Pasemos a la siguiente instrucción de suma importancia. El bloque de validación.


2.- Bloque validación de datos entrada.

Validar los datos de entrada evita al menos dos cosas: no perder tiempo en procesar datos que ya sabemos no nos devolverán información útil o que estos datos incorrectos provoque un error de ejecución y el programa se detenga.

Esta validación la haremos utilizando el condicional IF, que actuará como filtro según las restricciones que le indiquemos.

      /*-------------------------------------------------------------
      Bloque validación de datos de entrada 
      ---------------------------------------------------------------*/
      if (num1 > 0 && num2 > 0 &&
         isNaN(num1) == false && inNan(num2) == false){
Aquí van las instrucciones de división

}else {
alert("Ingrese solo números y que sean mayores a 0");
}

El ejercicio requiere conocer los números divisores comunes a dos números dados.

Por lógica, quedan descartadas las entradas de caracteres especiales como %&=# o los caracteres del alfabeto, simplemente porque para efecto de este ejercicio, no nos sirven.

El programa tampoco debería aceptar números negativos o fraccionarios. Así que la validación pasa por solo aceptar números enteros mayores a 0.  

En el bloque de declaración e iniciación de las variables, ya aplicamos un primer filtro a los datos de entrada con Number.parseInt. 

Todos los números fraccionarios serán convertidos a un número entero.

let num1 = Number.parseInt(prompt("Introduzca el 1er número"));

Los números negativos son todos los menores a 0, entonces solo basta indicar con el operador de comparación " > " que el dato debe ser mayor que 0 para ser válido.  

Y esta restricción debe ser cierta para ambas variables. Es decir, las dos entradas numéricas deben ser mayores a 0 y el operador lógico && obliga a que la condición se cumpla en ambos casos.

Si por ejemplo num1=8, pero num2=0, el programa no procesará los datos hasta tanto ambos sean valores numéricos. 

        num1 > 0 && num2 > 0

Esta validación se leería:  "Sí num1 es mayor que 0  Y num2 es mayor que 0", ejecute las instrucciones a continuación. 

Ya tenemos controlada la entrada de números negativos y fracciones, pero nos falta bloquear el ingreso de letras y caracteres especiales. 

Utilizaremos el método isNaN().

El método isNaN(variable) examina si el valor de la variable NO es un número. 

Si la variable no es un número, retorna True, pero SI es un número retorna False.

        isNaN(num1) == false && isNaN(num2) == false

Nota el uso del signo ==. Recuerda que en Javacript:

  • El signo = significa asignación. 
  • El signo == significa igualdad. 
  • El signo === significa igualdad estricta.


Si las variables num1 y num2 no son mayores a 0 y si tampoco son números, el programa lanzará un alerta solicitando ingresen la data correcta.

      
else {
        alert("Ingrese solo números y que sean mayores a 0");
      }

Hasta ahora el código va viéndose así:


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
   <script>
/*--------------------------------------------------------
      Bloque ingreso de datos e inicialización de variables 
   ---------------------------------------------------------*/

  let num1 = Number.parseInt(prompt("Introduzca el 1er número"));
  let num2 = Number.parseInt(prompt("Introduzca el 2do número"));
  let vector1 = [];
  let vector2 = [];
  let vector3 = [];

 /*--------------------------------------------------
   Bloque validación de datos de entrada 
 ----------------------------------------------------*/
      if (
        num1 > 0 && num2 > 0 &&
        isNaN(num1) == false && isNaN(num2) == false) {
           
-------instrucciones--------------    
      } else {
        alert("Ingrese solo números y que sean mayores a 0");
      }
    </script>
  </body>
</html>

3.- Bloque números divisibles del número dado.

Con los datos correctos, el programa podrá operar la primera instrucción que consiste en hallar los números divisores de num1 y num2.

/*-------------------------------------------------------------
   Bloque "Operación números divisibles" por el número dado
-------------------------------------------------------------*/

        for (let i = 1; i <= num1; i++) {
          if (num1 % i == 0) vector1.push(i);
        }

        for (let j = 1; j <= num2; j++) {
          if (num2 % j == 0) vector2.push(j);
        }

Los números divisores de un número, son todos los números menores e igual al número, comenzando en 1.

Ejemplo. 

Divisores de 10 son: 1, 2, 5, 10

Divisores de 15 son: 1,3,5,15

Para conocer el divisor de un número debemos ir dividiendo el número entre los números que le preceden, incluido el mismo número.

Ejemplo:

Sea 10 el número. Los números que le preceden son: 1,2,3,4,5,6,7,8,9,10.

Pero solo se debe considerar divisor, el número que divide a otro de manera exacta sin residuos.

Ejemplo:

10/1 = 10

10/2= 5

10/3= 3,3 ( 3 no es divisible de 10)

10/4= 2,5 (4 no es divisible de 10)

10/5= 2

Necesitamos por lo tanto dividir el número dado entre cada uno de sus predecesores. 

Utilizaremos un bucle For.

El bucle For necesita una variable de control que detenga la iteración cuando se alcance el objetivo. Esta variable de control la llamaremos “i”.

for (let i = 1; i <= num1; i++)

La variable “i” representará los números predecesores a las variables num1 y num2.  Se inicializa en 1. let i = 1

El ciclo For se repetirá hasta que la variable “i” sea igual o menor a las variables num1 y num2. i <= num1; 

Por cada repetición se incrementará en 1. i++

Supongamos que num1= 10. Si sustituimos la variable se vería así: 

for (let i = 1; i <= 10; i++)

Todo lo que esté dentro del bucle For, se ejecutará 10 veces.  

La variable "i" iniciará en 1, pero su valor se irá incrementando en 1 hasta llegar a 10 y el bucle parará de ejecutarse.

        for (let i = 1; i <= num1; i++) {
          if (num1 % i == 0) vector1.push(i);
        }

Se usa un condicional If para validar que solo se guarden en el vector los números que dividen a la variable.

El operador "%" o Modulus hace la división y recoge el residuo de la división. Si este residuo es igual a 0, el número es divisor del número dado.

Ejemplo

 i=1    ¿El residudo de 10/1==0?  Si.  (Se guarda en variable)

 i=2    ¿El residudo de 10/2==0? Si. (Se guarda en la variable )  

 i=3    ¿El residudo de 10/3==0? No. ( Se ignora.)

Siempre que la condición se cumpla, se guarda el valor de "i" en la variable, en este caso el vector1. 

Ese valor se agrega utilizando el método de arrays "push()".

if (num1 % i == 0) vector1.push(i);

Se crea otro bloque, siguiendo iguales pasos para hallar los números que dividen a num2. 

Pero debemos ponerle otro nombre a la variable de control que llamaremos "j".

        for (let j = 1; j <= num2; j++) {
          if (num2 % j == 0) vector2.push(j);
        }

Así va el código con este último bloque:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*---------------------------------------------------------
      Bloque ingreso de datos e inicialización de variables 
      ----------------------------------------------------------*/
      let num1 = Number(prompt("Introduzca el 1er número"));
      let num2 = Number(prompt("Introduzca el 2do número"));
      let vector1 = [];
      let vector2 = [];
      let vector3 = [];
      /*-----------------------------------------------------
      Bloque validación de datos de entrada 
      -------------------------------------------------------*/
      if (
        num1 != 0 &&
        num2 != 0 &&
        isNaN(num1) == false &&
        inNan(num2) == false
      ) {
     /*------------------------------------------------------
       Bloque "Operación números divisibles" por el número dado
     --------------------------------------------------------*/

        for (let i = 1; i <= num1; i++) {
          if (num1 % i == 0) vector1.push(i);
        }

        for (let j = 1; j <= num2; j++) {
          if (num2 % j == 0) vector2.push(j);
        }

Ya tenemos los números que son divisores de num1 y num2. Ahora necesitamos conocer los números comunes a ambas variables.


4.- Bloque Condición según longitud del vector

Necesitamos buscar que los números divisores de num1 guardados en el vector1 tengan su par en el vector2 que guarda los divisores de num2.

Utilizaremos dos bucles For anidados. El primero que llamaremos “k”, recorrerá cada uno de los elementos del vector1 comparándolo con cada elemento del vector2  y a este segundo bucle for lo llamaremos  “m”.

for (let k = 0; k <= vector1; k++) {
     for (let m = k; l <= vector2; m++) {
         ----instrucciones----
            }
          }
        

Pero, ¿cuál de los vectores en discusión debe ser tomado como punto de referencia? 

El que tenga menor longitud

Para hacerlo más fácil de visualizar, supongamos que tenemos vectores con los siguientes valores:

vector1= [1, 2, 3,4 ,5]

vector2= [1,2,3,4,5,6,7,8,9,10]

Cada elemento del vector1 debe compararse con cada elemento del vector2.  Como solo tiene 5 elementos, el tiempo de ejecución se hace más corto.

El método length, nos devuelve la longitud del vector.

       /*-------------------------------------------------------
         Bloque Condición según Longitud de vectores
        ---------------------------------------------------------*/
        if (vector1.length <= vector2.length) {
        }else{
            }

Usamos nuevamente un condicional If para validar cuando un vector es menor a otro, porque dependiendo de cuál sea el menor se ejecutarán diferentes acciones.


5.- Bloque comparación entre vectores

En este bloque usaremos los índices del vector, para tomar el número divisor guardado en esa dirección. Por eso la variable inicia en 0  y al tope representado por vector1.length se le resta 1. ¿Por qué?

 
/*-------------------------------------------------------------
   Bloque comparación de vector1 con cada elemento del vector2
  --------------------------------------------------------------*/

   for (let k = 0; k <= vector1.length - 1; k++) {
     for (let m = k; l <= vector2.length; m++) {
        if (vector1[k] === vector2[m]) vector3.push(vector1[k]);
            }
          }
        }

Supongamos que:

Vector1= [1,2,4,6,8]

Para acceder a los elementos, se ubica por su índice. 

Índice      Elemento

0        =        1

1        =       2

2        =       4

3        =       6

4        =       8

vector1 es un vector de 5 elementos pero su posición o índice se inician siempre en 0.  Es decir, el número de elementos no coincide con el número de posiciones, porque en los arrays, los índices se enumeran partiendo de 0.  

Como el método length cuenta el número de elementos, se debe restar 1 para coincidir con el índice del vector.

for (let k = 0; k <= vector1.length-1; k++) 

  • let k=0; iniciará el recorrido de las posiciones del vector1, comenzando en la posición 0.
  • k <= 5 – 1,  se compara cada vez el valor de k con la condición.
  • K++, se incrementa el valor de k en 1.

Vueltas             Recorrido en frío:

1               for (let k = 0; 0 <= (5 – 1); 0++)      0  es menor que 4, se incrementa

2              for (let k = 1; 1 <= 4; 1++)               1  es menor que 4, se incrementa

3              for (let k = 2; 2 <= 4; 2++)               2 es menor que 4, se incrementa

4              for (let k = 3; 3 <= 4; 3++)               3 es menor que 4, se incrementa

5              for (let k = 4; 4 <= 4; 5++)    Se cumple la condición y se detiene.

Toma en cuenta que restar 1 a length, es útil solo cuando necesitamos acceder a la data que se almacena en el vector, según su índice o posición.

Entendido esto, pasemos a la construcción del bloque de comparación de vectores para hallar los divisores comunes de ambos.


Como dije, es necesario utilizar dos bucles For, uno que leerá la información del vector1, y otro bucle For que leerá la información del vector2.

El vector de menor longitud es el vector que se toma como punto de referencia que llevará el control de la iteración entre los vectores. 

El vector de mayor longitud es contra quien se hará la comparación, este vector debe ir dentro del cuerpo del vector de menor longitud, así:


for (let k = 0; k <= vector menor-1; k++) {

   for (let m = 0; m <= vector mayor-1; m++){

}

}

Suponiendo tengamos estos datos:

vectorMenor= [1,2,4]  =>  bucle for k

vectorMayor= [1,2,4,8]  => bucle for m

 

vectorMenor =  1, 2, 4     elementos del vector  3

     K=                0, 1, 2       índices del vector 2

 

vectorMayor =  1, 2, 4, 8     elementos del vector 4

     K=                 0, 1, 2, 3               índices del vector  3


Simulación en frío

 

(k = 0; 0 <= 3-1; 0++)     elemento 1 posición 0

    (m = 0; 0 <= 4-1; 0++)  => elemento 1 en la posición 0

(m = 1; 1 <= 4-1; 1++)  => 2

(m = 2; 2 <= 4-1; 2++)  => 4

(m = 3; 3 <= 4-1; 3++)  => 8    Se ejecuta y regresa al bucle for k.

 

 (k = 1; 1 <= 3-1; 1++)    elemento 2 posición 1

(m = 0; 0 <= 4-1; 0++)  => 1

(m = 1; 1 <= 4-1; 1++)  => elemento 2  en la posición 1

(m = 2; 2 <= 4-1; 2++)  => 4

(m = 3; 3 <= 4-1; 3++)  => 8    Se ejecuta y regresa al bucle for k.

 

(k = 2; 2 <= 3-1; 2++)   elemento 4 posición 2 // Se ejecuta y se detiene.

(m = 0; 0 <= 4-1; 0++)  => 1

(m = 1; 1 <= 4-1; 1++)  => 2

(m = 2; 2 <= 4-1; 2++)  =>elemento 4 posición 2

(m = 3; 3 <= 4-1; 3++)  => 8    Se ejecuta y regresa al bucle for k.


Como puedes ver, cada elemento del vector menor es confrontado con uno de los elementos del vector mayor

Cuando se completa un ciclo for m, regresa al ciclo for k que se incrementa en 1 y vuelve a ejecutar el ciclo for m.  

Esto se repite hasta que k cumple con la condición.


          for (let k = 0; k <= vector1.length - 1; k++) {
            for (let m = 0; m <= vector2.length; m++) {
              if (vector1[k] == vector2[m]) vector3.push(vector1[k]);
            }
          }

Y es dentro del cuerpo del ciclo for m que abriremos una condición que si se cumple guardará el número común a ambos vectores en otro vector que llamamos vector3.

Cuando  vector1[k] sea igual que vector2[m],  el valor que esté almacenado en la posición k, se guardará en el vector3.

Es decir si el elemento del vector1[0] es igual al elemento del vector2[0],  se guardará en la posición 0 del vector3, utilizando el método push que se explicó unos bloques arriba.

En caso que el vector2 tenga menor longitud, se invierten los valores.

   
else {
  /*-------------------------------------------------------------
   Bloque comparación de vector2 con cada elemento del vector1
  --------------------------------------------------------------*/

    for (let k = 0; k <= vector2.length - 1; k++) {
      for (let m = k; m <= vector1.length; m++) {
       if (vector2[k] === vector1[m]) vector3.push(vector2[k]);
       }
      }
     }

Así es como va la construcción del algoritmo:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, 
    initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
  /*-------------------------------------------------------------
  Bloque ingreso de datos e inicialización de variables 
 ---------------------------------------------------------------*/
      let num1 = Number.parseInt(prompt("Introduzca el 1er número"));
      let num2 = Number.parseInt(prompt("Introduzca el 2do número"));
      let vector1 = [];
      let vector2 = [];
      let vector3 = [];
  /*------------------------------------------------------------
  Bloque validación de datos de entrada 
   -------------------------------------------------------------*/
      if (
        num1 > 0 &&
        num2 > 0 &&
        isNaN(num1) == false &&
        isNaN(num2) == false
      ) {
 /*-------------------------------------------------------------
  Bloque "Operación números divisibles" por el número dado
 -------------------------------------------------------------*/

        for (let i = 1; i <= num1; i++) {
          if (num1 % i == 0) vector1.push(i);
        }

        for (let j = 1; j <= num2; j++) {
          if (num2 % j == 0) vector2.push(j);
        }

 /*-------------------------------------------------------------
  Bloque Condición según Longitud de vectores
  --------------------------------------------------------------*/
        if (vector1.length <= vector2.length) {
  /*-------------------------------------------------------------
   Bloque comparación de vector1 con cada elemento del vector2
 ---------------------------------------------------------------*/

    for (let k = 0; k <= vector1.length - 1; k++) {
     for (let m = 0; m <= vector2.length; m++) {
      if (vector1[k] == vector2[m]) vector3.push(vector1[k]);
       }
      }
    } else {
   /*------------------------------------------------------------
  Bloque comparación de vector2 con cada elemento del vector1
  --------------------------------------------------------------*/

     for (let k = 0; k <= vector2.length - 1; k++) {
      for (let m = k; m <= vector1.length; m++) {
       if (vector2[k] === vector1[m]) vector3.push(vector2[k]);
      }
     }
    }

Ahora solo nos resta trabajar en el bloque de impresión de los resultados.

   
/*-------------------------------------------------------------
  Bloque visualizacion divisores / termina la ejecución del prog
  --------------------------------------------------------------*/

 document.write("Divisores de " + num1 + " : " + vector1 + "<br>");
 document.write("Divisores de " + num2 + " : " + vector2 + "<br>");
 document.write("Divisores comunes: " + vector3 + "<br>");

  • Document.write mostrará lo que le indiquemos dentro de los paréntesis en pantalla.
  • Las cadenas deben ir entre comillas y separadas por el signo + de las variables.
  • La etiqueta “<br>” hace un salto de línea, para evitar aglomeración de los resultados.


Los resultados deberían lucir así en la ventana del navegador:



<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
  /*-------------------------------------------------------------
  Bloque ingreso de datos e inicialización de variables 
  ---------------------------------------------------------------*/
 let num1 = Number.parseInt(prompt("Introduzca el 1er número"));
 let num2 = Number.parseInt(prompt("Introduzca el 2do número"));
let vector1 = [];
 let vector2 = [];
 let vector3 = [];
  /*-------------------------------------------------------------
  Bloque validación de datos de entrada 
 ---------------------------------------------------------------*/
      if (
        num1 > 0 &&
        num2 > 0 &&
        isNaN(num1) == false &&
        isNaN(num2) == false
      ) {
   /*------------------------------------------------------------
  Bloque "Operación números divisibles" por el número dado
  --------------------------------------------------------------*/

        for (let i = 1; i <= num1; i++) {
          if (num1 % i == 0) vector1.push(i);
        }

        for (let j = 1; j <= num2; j++) {
          if (num2 % j == 0) vector2.push(j);
        }

  /*-------------------------------------------------------------
   Bloque Búsqueda de elementos iguales entre los vectores
  ---------------------------------------------------------------*/

    /*-----------------------------------------------------------
   Bloque Condición según Longitud de vectores
    -----------------------------------------------------------*/
        if (vector1.length <= vector2.length) {
  /*-------------------------------------------------------------
    Bloque comparación de vector1 con cada elemento del vector2
 ---------------------------------------------------------------*/

   for (let k = 0; k <= vector1.length - 1; k++) {
      for (let m = 0; m <= vector2.length; m++) {
         if (vector1[k] == vector2[m]) vector3.push(vector1[k]);
            }
          }
        } else {
   /*-------------------------------------------------------------
     Bloque comparación de vector2 con cada elemento del vector1
 ---------------------------------------------------------------*/

  for (let k = 0; k <= vector2.length - 1; k++) {
     for (let m = k; m <= vector1.length; m++) {
       if (vector2[k] === vector1[m]) vector3.push(vector2[k]);
            }
          }
        }

  /*-------------------------------------------------------------
    Bloque visualizacion divisores / termina la ejecución del prog
 ---------------------------------------------------------------*/

 document.write("Divisores de " + num1 + " : " + vector1 + "<br>");
 document.write("Divisores de " + num2 + " : " + vector2 + "<br>");
 document.write("Divisores comunes: " + vector3 + "<br>");
     
 } else {
  /*-------------------------------------------------------------
    Bloque Error data de inicio / reinicia el prog.
  ---------------------------------------------------------------*/
        alert("Entre solo números y/o diferentes de 0");
      }
    </script>
  </body>
</html>


Seguro hay un algoritmo más eficiente y con menos código que resuelve el enunciado, pero este no deja de ser útil para probar la sintaxis de Javascript. 


 

The biggest difference between stupidity and intelligence is: When you're stupid, you think you know everything, without questioning and when you're intelligent, you question everything you think you know. 

Richard Feynman





The biggest difference between stupidity and intelligence is: When you're stupid, you think you know everything, without questioning and when you're intelligent, you question everything you think you know.

Comentarios

Entradas populares