diff --git a/Roadmap/02 - FUNCIONES Y ALCANCE/javascript/pedamoci.js b/Roadmap/02 - FUNCIONES Y ALCANCE/javascript/pedamoci.js new file mode 100644 index 0000000000..abbc0c92d0 --- /dev/null +++ b/Roadmap/02 - FUNCIONES Y ALCANCE/javascript/pedamoci.js @@ -0,0 +1,106 @@ +// ----------------------- FUNCIONES BASICAS ----------------------- + // Sin parámetros ni retorno + function saludar() { // función normal + console.log('Hola, mundo') + } + const preguntar = ()=> { // función flecha + console.log('Todo bien?') + } + saludar() + preguntar() + + // Con parámetros sin retorno + function saludoPersonalizado(nombre) { + console.log(`Hola, ${nombre}`) + } + const nacimiento = (edad) => { + const actualYear = new Date().getFullYear() + console.log('Año de nacimiento: ', actualYear - edad) + } + saludoPersonalizado('Jaime') + nacimiento(98) + + // Con parámetros y retorno + function sumar(num1, num2) { + return num1 + num2 + } + const multiplicar = (num1, num2) => { + return num1 * num2 + } + console.log('Suma: ', sumar(5, 3)) + console.log('Multiplicación: ', multiplicar(7, 8)) + +// ----------------------- FUNCIONES DENTRO DE FUNCIONES ----------------------- + // Función normal dentro de función normal + function areaTrianguloRectangulo(altura, base) { + const areaCuadrado = altura * base + function area(areaCuadrado) { + return areaCuadrado / 2 + } + return area(areaCuadrado) + } + console.log('Area del triángulo rectángulo: ', areaTrianguloRectangulo(10, 5)) + + // Función flecha dentro de función flecha + const volumenCilindro = (radio, altura) => { + const areaCirculo = (r) => Math.PI * (r ** 2) + return areaCirculo(radio) * altura + } + console.log('Volumen de la cilindro: ', volumenCilindro(3, 10)) + + // Función flecha dentro de función normal + function areaHexagono(lado, base, hipotenusa) { + const perimetro = lado * 6 + const apotema = (b, h) => { + return Math.sqrt((-(b **2)) + (h ** 2)) + } + return (perimetro * apotema(base, hipotenusa)) / 2 + } + console.log('Area del hexágono: ', areaHexagono(6, 10, 12)) + + // Función normla dentro de función flecha + const areaCirculo = (radio) => { + function area(r) { + return Math.PI * (r ** 2) + } + return area(radio) + } + console.log('Area del círculo: ', areaCirculo(7)) + +// ----------------------- FUNCIONES DENTRO DEL LENGUAJE ----------------------- + console.log('Según la función isFinite 10/3 es finito? ', isFinite(10/3)) + +// ----------------------- VARIABLES LOCALES Y GLOBALES ----------------------- + let global = 'Soy global' // Variable global + function bloqueUno () { + let localFunction = 'Soy local de función' // Variable local de la función + const bloqueDos = () => { + let localFunctionFlecha = 'Soy local de función flecha' // Variable local de la función flecha + console.log(`La variable global es: ${global}, la variable local de la función es: ${localFunction} y la variable local de la función flecha es: ${localFunctionFlecha}`) + } + console.log(`La variable global es: ${global}, la variable local de la función es: ${localFunction} y la variable local de la función flecha es: UNDIFINED`) + bloqueDos() + } + console.log(`La variable global es: ${global}, la variable local de la función es: UNDIFINED y la variable local de la función flecha es: UNDIFINED`) + bloqueUno() + +// ----------------------- DIFICULTAD EXTRA ----------------------- +function impresora(s1, s2) { + let cantNumImpresos = 0 + for (let i = 1; i <= 100; i++) { + if (i % 3 === 0 && i % 5 === 0) { + console.log(s1 + s2) + } else if (i % 3 === 0) { + console.log(s1) + } else if (i % 5 === 0 ) { + console.log(s2) + } else { + cantNumImpresos++ + console.log(i) + } + } + return cantNumImpresos +} +let str1 = prompt('ingresa la primera cadena de texto: ') +let str2 = prompt('ingresa la segunda cadena de texto: ') +console.log(`Se ha impreso el un número en lugar del texto: ${impresora(str1, str2)} veces`) \ No newline at end of file diff --git a/Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/pedamoci.js b/Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/pedamoci.js new file mode 100644 index 0000000000..73d5248e83 --- /dev/null +++ b/Roadmap/03 - ESTRUCTURAS DE DATOS/javascript/pedamoci.js @@ -0,0 +1,208 @@ +// ----------------------------- ESTRUCTURAS DE DATOS ----------------------------- + // ARRAYS + + const frutas = new Array('Manzana', 'Pera', 'Banana') + // OBJECTS + + const persona = new Object({nombre: 'Aang', edad: 112, profesion: 'Avatar'}); + // SETS + + const notasMusicales = new Set(['do', 're', 'mi', 'fa', 'sol', 'la']); + // MAPS + + const capacidad = new Map([[0, "zero"], [1, 'one'], [2, 'two'], [3, 'tree'], [4, 'four']]); + +// ----------------------------- OPERACIONES BASICAS ----------------------------- + // Inserción + frutas.push('Naranja') // Array + persona.tribu = 'Nómadas del aire' // Object + notasMusicales.add('si') // Set + capacidad.set(5, 'five') // Map + + // Borrado + frutas.splice(1, 1) // Array + delete persona.edad // Object + notasMusicales.delete('fa') // Set + capacidad.delete(5) //Map + + // Actualización + frutas[0] = 'Mango' // Array + persona.profesion = 'Maestro del aire' // Object + // Los Sets no permiten actualización directa + capacidad.set(3, 'three') // Map + + // Ordenación + frutas.sort() // Array + // Los Objects no tienen funciones de ordenación directa + // Los Sets no tienen funciones de ordenación directa + // Los Maps no tienen funciones de ordenación directa + +// ----------------------------- DIFICULTAD EXTRA ----------------------------- +let agenda = new Object({ + 3321904500: 'Erick', + 6598204500: 'Jaime', + 3321968740: 'Raul', + 3654928824: 'Mateo', + 1218322247: 'Laura', + 9633455572: 'Miguel', + 3321994421: 'Omar', + 2076589124: 'Oscar', + 4863465825: 'Jose', + 5739514862: 'Fernando', + 8134679852: 'Eloy', + 7159852456: 'Daniel', + 3322577770: 'Erick', + 3999994500: 'Erick', +}) + +function verificarInfo() { + //Verifica si el nombre o número ingresado por el usuario esta en la agenda + while (true) { + let info = prompt("Ingrese el nombre o telefono") + if (Object.hasOwn(agenda, parseInt(info))) { + return {'tel': info} + } else if (Object.values(agenda).includes(info)) { + return {'name': info} + } + alert("Persona/Telefono NO agendado/a") + } +} + +function verificarTel() { + //Verifica que el número de telefono ingresado tenga entre 8 y 11 digitos + while (true) { + let tel = parseInt(prompt("Ingrese el teléfono (debe tener entre 8 y 11 dígitos)")) + if (!isNaN(tel) && tel.toString().length >= 8 && tel.toString().length <= 11) { + return tel; + } + alert("Número de teléfono inválido. Debe tener entre 8 y 11 dígitos.") + } +} + +function updateNombre() { + //Actualiza el nombre de un contacto + let infoUpdate = verificarInfo() + if (infoUpdate.name !== undefined) { + // busca a los contactos por nombre si hay varios devuelve los numeros y si hay uno permite cambiar el nombre + let tel = Object.keys(agenda).filter(key => agenda[key] === infoUpdate.name) + if (tel.length !== 1){ + alert(`Tienes varios contactos con ese nombre, verifica y actualiza el contacto que quieres por alguno de estos números ${tel}`) + } else { + let newName = prompt('Ingrese el nuevo nombre') + agenda[parseInt(tel)] = newName + alert(`Se ha actualizado el nombre del número ${tel} por ${newName}`) + } + } else { + // busca el contacto por el telefono y le cambia el nombre + let newName = prompt('Ingrese el nuevo nombre') + agenda[parseInt(infoUpdate.tel)] = newName + alert(`Se ha actualizado el nombre del número ${infoUpdate.tel} por ${newName}`) + } +} + +function updateTelefono(tel) { + // Actualiza el telefono de un contacto + let infoUpdate = verificarInfo() + if (infoUpdate.name !== undefined) { + // busca a los contactos por nombre si hay varios devuelve los numeros y si hay uno permite cambiar el telefono + let tel = Object.keys(agenda).filter(key => agenda[key] === infoUpdate.name) + if (tel.length !== 1){ + alert(`Tienes varios contactos con ese nombre, verifica y actualiza el contacto que quieres por alguno de estos números ${tel}`) + } else { + let newTel = verificarTel() + delete agenda[tel] + agenda[newTel] = infoUpdate.name + alert(`Se ha actualizado el número de ${infoUpdate.name} a ${newTel}`) + } + } else { + // busca el contacto por el telefono y le cambia el telefono + let newTel = verificarTel() + let lastName = agenda[infoUpdate.tel] + delete agenda[infoUpdate.tel] + agenda[newTel] = lastName + alert(`Se ha actualizado el número de ${lastName} a ${newTel}`) + } +} + +function search() { + // te permite buscar, insertar, actualizar y borrar un contacto + // ademas te pregunta si queres hacer otra operacion + let operation = prompt("Ingrese la operación a realizar: buscar, insercion, actualizar, borrar") + switch (operation) { + case "buscar": + let infoSearch = verificarInfo() + if (infoSearch.name !== undefined) { + // busca los telefonos que coincidan con el nombre ingresado y devuelve todos + let tel = Object.keys(agenda).filter(key => agenda[key] === infoSearch.name) + if (tel.length !== 1){ + alert(`Tienes ${tel.length} contactos llamados ${infoSearch.name} con los números ${tel}`) + } else{ + alert(`El telefono de ${agenda[tel]} es ${tel}`) + } + } else { + // busca el nombre del número de telefono ingresado + let name = agenda[infoSearch.tel] + alert(`El dueño del telefono ${infoSearch.tel} es ${name}`) + } + break; + + case "insercion": + let name = prompt("Ingrese el nombre") + tel = verificarTel() + agenda[tel] = name + alert(`Se ha agendado a ${name} con el número ${tel}`) + break; + + case "actualizar": + let updateOption = alert('¿Que queres actualizar nombre o telefono?') + while (updateOption !== 'nombre' && updateOption !== 'telefono') { + (updateOption === 'nombre') ? updateNombre() + : updateTelefono() + } + break; + + case "borrar": + let infoRemove = verificarInfo() + if (infoRemove.name !== undefined) { + // busca todos los números que estan agendados con el mismo nombre + let tel = Object.keys(agenda).filter(key => agenda[key] === infoRemove.name) + if (tel.length !== 1){ + let aviso = prompt('Tienes varios contactos con ese nombre, ¿Deseas borrar todos? Y/N') + while (aviso !== 'Y' && aviso !== 'N') { + if (aviso === 'Y'){ + let telRemoved = [...tel] + while (tel.length !== 0) { + // va eliminando de un telefono a la vez desde el último hasta el primero + let i = tel.length - 1 + delete agenda[parseInt(tel[i])] + tel.pop() + } + alert(`Los contacto con nombre ${infoRemove.name} y números ${telRemoved} han sido borrado`) + break; + } else { + alert(`Los números que tienes agendados como ${infoRemove.name} son ${tel}`) + break; + } + } + } else { + delete agenda[tel] + alert(`El contacto con nombre ${infoRemove.name} y número ${tel} ha sido borrado`) + } + } else { + let nameRemoved = agenda[infoRemove.tel] + delete agenda[infoRemove.tel] + alert(`El contacto con nombre ${nameRemoved} y número ${infoRemove.tel} ha sido borrado`) + } + break; + default: + break; + } + let stop = prompt('Quieres hacer otra operación? Y/N') + while (stop !== 'Y' && stop !== 'N') { + if (stop === 'Y') { + search() + } break; + } +} + +search() \ No newline at end of file diff --git a/Roadmap/04 - CADENAS DE CARACTERES/javascript/pedamoci.js b/Roadmap/04 - CADENAS DE CARACTERES/javascript/pedamoci.js new file mode 100644 index 0000000000..2beefa887d --- /dev/null +++ b/Roadmap/04 - CADENAS DE CARACTERES/javascript/pedamoci.js @@ -0,0 +1,236 @@ +let lorem = new String('Lorem ipsum, dolor sit amet consectetur adipisicing elit. Earum, eum! Ipsam odit repellendus dolorem dolor ut sequi beatae, odio earum dignissimos aut consequuntur quibusdam, ad voluptas unde atque, sapiente inventore!') +let hello = 'Hello' +let world = 'world' + +// ----------------------- OPERACIONES DE CADENAS ----------------------- + // at() --> busca un caracter o elemento por posición empenzando desde el 0, con números negativos va de atras hacia delante empezando por -1 + console.log(lorem.at(25)) // --> devuelve la 'e' de amet + console.log(lorem.at(-32)) // --> devuelve ' ' el espacio entre voluptas y unde + + // charAt() --> busca un caracter por posición empenzando desde el 0, no acepta números negativos y no devuelve espacios, saltos de linea, etc. + console.log(lorem.charAt(45)) // --> devuelve la 's' de adipisicing + console.log(lorem.charAt(64)) // --> devuelve la '' ya que es el espacio entre Earum y eum + + // charCodeAt() --> devuelve el codigo (valor del 0 al 65523 del codigo UTF-16) de un caracter o elemento buscado por posición empenzando desde el 0, no acepta números negativos y si el caracter es un emoji, símbolo matemático o caracter de un idoma raro el valor devuelto es incorrecto + console.log(lorem.charCodeAt(45)) // --> devuelve 115 del codigo en UTF-16 de la 's' de adipisicing + console.log(lorem.charCodeAt(64)) // --> devuelve 32 del codigo en UTF-16 ya que es el espacio entre Earum y eum + + // charCodeAt() --> devuelve el codigo (valor del 0 al 65523 que puede contener letras del codigo UTF-16) de cualquier caracter buscado por posición empenzando desde el 0, no acepta números negativos + console.log(lorem.codePointAt(45)) // --> devuelve 115 del codigo en UTF-16 de la 's' de adipisicing + console.log(lorem.codePointAt(64)) // --> devuelve 32 del codigo en UTF-16 ya que es el espacio entre Earum y eum + + // concant() --> concatena + console.log(hello.concat(' ', world, ', mensaje número ', 1)); // --> devuelve 'Hello world, mensaje número 1' + + // endsWith() --> devuelve true | false comparando el string ingresado con el final de la cadena + console.log(lorem.endsWith('!')); // --> true + console.log(lorem.endsWith('inventore!')); // --> true + console.log(lorem.endsWith('Lore', 4)); // --> true ya que compara el string con como termina la cadena hasta (sin incluir el caracter) la posición indicada + console.log(lorem.endsWith('Lorem', 4)); // --> false + + // includes() --> devuelve true | false revisando si el string ingresado esta en la cadena, es case sensitive (distingue entre mayúsculas y minúsculas) + console.log(lorem.includes('!')); // --> true + console.log(lorem.includes('inventore!')); // --> true + console.log(lorem.endsWith('lorem')); // --> true ya que dentro de la palabra dolorem se encuaantra 'lorem' + console.log(lorem.endsWith('Amet')); // --> false + + // indexOf() --> busca una coincidencia en la cadena con el string ingresado y devuelve la posicion del primer caracter de la primera coincidencia + console.log(lorem.indexOf('dolor')); // --> devuelve 13 (ignora la posición 93 y 101 que también lo cumplen) + console.log(lorem.indexOf(' ')); // --> devuelve 5 + + // isWellFormed() --> devuelve true | false si el string tiene un codigo UTF-16 completo + const correctUTF16 = "\uD83D\uDE00"; // el '😄' al ser una simbolo complejo esta formado por dos partes + const incorrectUTF16 = "\uD83D"; // Una parte del codigo UTF-16 de '😄' + console.log(correctUTF16.isWellFormed()); // --> devuelve true + console.log(incorrectUTF16.isWellFormed()); // --> devuelve false + + // lastIndexOf() --> busca una coincidencia en la cadena con el string ingresado y devuelve la posicion del primer caracter de la última coincidencia + console.log(lorem.indexOf('dolor')); // --> devuelve 101 (ignora la posición 13 y 93 que también lo cumplen) + console.log(lorem.indexOf(' ')); // --> devuelve 207 + + // localCompare() --> compara la cadena de la derecha con la de la izquerda, si la de la deracha va antes en orden alfabetico devuelve -1, si va despues 1 y 0 si son iguales según llas reglas de comparación + console.log("manzana".localeCompare("banana")); // --> 1 + console.log("banana".localeCompare("manzana")); // --> -1 + console.log("pera".localeCompare("pera")); // --> 0 + console.log("réservé".localeCompare("RESERVE", 'es', { sensitivity: "base"})) // --> 0 ya que ignora el acento y las mayúsculas + console.log("ä".localeCompare("z", "es")); // --> -1 ya que 'ä' en el español se la considera como una variante de 'a' + console.log("ä".localeCompare("z", "sv")); // --> 1 ya que 'ä' es parte del alfabeto sueco y va despues de la 'z' + + // match() --> busca a través de una expreción regular (https://regex101.com) los caracteres o las cadenas que coincidan + console.log(lorem.match(/[A-Z]/g)); // --> L, E, I ya que devuelve las letras mayúsculas desde la 'A' a la 'Z' + console.log(lorem.match(/\b\w*um\w*\b/g)); // --> ipsum, Earum, eum, earum ya que devuelve las palabras que contengan 'um' + + // matchAll() --> busca a través de una expreción regular (https://regex101.com) los caracteres o las cadenas que coincidan y la devuelve incluyendo los grupos capturables + const array = [...lorem.matchAll(/s(a)\w*(ie)\w*(e)/g)] + console.log(array[0]) // --> sapiente, a, ie, e primero devuelve sapiente ya que busca una palabra 's'-'a'-cualquier caracter-'ie'-cualquier caracter-'e' y despues devuelve cada grupo 'a', 'ie', 'e' + + // normalize() --> transforma el código dado a uno normalizado + const name1 = "\u0041\u006d\u00e9\u006c\u0069\u0065" // --> Amélie, el codigo de 'é' esta dado por \u00e9 + const name2 = "\u0041\u006d\u0065\u0301\u006c\u0069\u0065" // --> Amélie, el codigo de 'é' esta dado por \u0065\u0301 el primero correspode a 'e' y el segundo al acento + console.log(name1 === name2) // --> False + console.log(name1.normalize('NFC') === name2.normalize('NFC')); // --> True + + // padEnd() --> agrega el caracter/string que quieras al final de un string hasta llegar a la longitud ingresada, empieza desde 1 (siempre devuelve como mínimo el string original) + console.log(hello.padEnd(6, ',').padEnd(7, ' ') + world) // --> Hello, world + + // padStart() --> agrega el caracter/string que quieras al inicio de un string hasta llegar a la longitud ingresada, empieza desde 1 (siempre devuelve como mínimo el string original) + console.log('9725'.padStart(10, '*')) // --> ******9725 + + // repeat() --> repite el string la cantidad de veces ingresadas + console.log(`I feel ${'Happy! '.repeat(3)}`) // --> I feel Happy! Happy! Happy! + + // replace() --> remplaza la primer coincidencia de lo indicado a través de una expreción regular o por un string por el string ingresado + console.log(lorem.replace('dolor', 'DOLOR')) // --> remplaza el primer string 'dolor' (indice 13) por 'DOLOR', ignorando los de indice 93 y 101 + + // replaceAll() --> remplaza todas las coincidencia de lo indicado a través de una expreción regular o por un string por el string ingresado + console.log(lorem.replaceAll('dolor', 'DOLOR')) // --> remplaza todos los string 'dolor' (indice 13, 93, 101) por 'DOLOR' + + // search() --> busca la primer coincidencia de lo indicado a través de una expreción regular o por un string + console.log(lorem.search('Ipsam')) // --> 70 ya que es el indice donde empieza el strin 'Ipsam' + + // slice() --> devuelve la parte indicada de un string, acepta números negativos + console.log(lorem.slice(-99,-63)) // --> tae, odio earum dignissimos aut cons + console.log(lorem.slice(151)) // --> consequuntur quibusdam, ad voluptas unde atque, sapiente inventore! + + // split() --> divede la cadena de texto por el string o la expreción regular ingresada + console.log(lorem.split(' ')) // --> divide el texto en palabras + console.log(lorem.split('')) // --> divide el texto en caracteres + + // startWith() --> verifica si en una posición hay un string que empiece como el string ingresado (NO acepta expresiones regelures) + console.log(lorem.startsWith('Lor')) // --> True el texto comienza com Lorem... + console.log(lorem.startsWith('lor', 15)) // --> True en el indice 15 inicia un string 'lor' (palabra original 'dolor' indice 13) + + // substring() --> devuelve la parte indicada -1 de un string, los números negativos los interpreta como 0 y no importa el orden en el que ingreses los datos + console.log(lorem.substring(99,55)) // --> t. Earum, eum! Ipsam odit repellendus dolore ya que invierte los valores al ser el de la izquierda mas grande y el caracter de indice 99 no lo devuelve + + // toLocalLowerCase() --> devuelve el string ingresado en la minúscula del idioma ingresado + console.log("İstanbul".toLocaleLowerCase("en-US") === "İstanbul".toLocaleLowerCase("tr")) // --> False ya que la 'İ' en minúscula en "en-US" es ditinta a la de "tr" + + // toLocalUpperCase() --> devuelve el string ingresado en la minúscula del idioma ingresado + console.log("istanbul".toLocaleUpperCase("en-US") === "istanbul".toLocaleUpperCase("tr")) // --> False ya que la 'i' en minúscula en "en-US" es ditinta a la de "tr" + + // toLowerCase() --> devuelve el string en minúscula + console.log("İstanbul".toLowerCase("en-US") === "İstanbul".toLowerCase("tr")) // --> True ya que vuelve el string insensible a la configuración regional + + // toString() --> devuelve un string de lo ingresado + const num = 123 + console.log(num.toString()); + + // toUpperCase() --> devuelve el string en mayúcula + console.log("istanbul".toUpperCase("en-US") === "istanbul".toUpperCase("tr")) // --> True ya que vuelve el string insensible a la configuración regional + + // toWellFormed() --> transforma el codigo UTF-16 a un caracter legible + console.log('ab\uD83D\uDE04c'.toWellFormed()) // --> ab😄c transformo '\uD83D\uDE04' en 😄 + + // trim() --> quita los espacios en blanco del comienzo y final de un string (NO quita los saltos de linea) + console.log(` ${hello}, ${world}! `.trim()) // --> 'Hello, world!' + + // trimEnd() --> quita los espacios en blanco del final de un string (NO quita los saltos de linea) + console.log(` ${hello}, ${world}! `.trimEnd()) // --> ' Hello, world!' + + // trimStart() --> quita los espacios en blanco del comienzo de un string (NO quita los saltos de linea) + console.log(` ${hello}, ${world}! `.trimStart()) // --> 'Hello, world! ' + + // valueOf() --> devuelve el valor de un objeto string + const stringObj = new String("foo") + console.log(stringObj) // --> [String: 'foo'] + console.log(stringObj.valueOf()) // --> 'foo' + console.log('Hello, world!'.valueOf()) // --> 'Hello, world!' + + // [Symbol.iterator]() --> devuelde cada simbolo de un string (se usa si tenes codigo UTF-16 para separar por caracter) + const str = "A\uD835\uDC68B\uD835\uDC69C\uD835\uDC6A"; + const strIter = str[Symbol.iterator](); + console.log(strIter.next().value) + console.log(strIter.next().value) + console.log(strIter.next().value) + console.log(strIter.next().value) + console.log(strIter.next().value) + console.log(strIter.next().value) + + // length --> devuelve la cantidad de caracteres que tiene un string + console.log(lorem.length) // --> 218 + +// -------------------------- DIFICULTAD EXTRA -------------------------- +function palindromos(word) { + let i = 0 + let j = word.length - 1 + while (i <= word.length/2) { + // recorre la palabra hasta la mitad ya que más seria redundate debido + // a que va comparando los caracteres del inicio con los del final + if (word[i].toLowerCase !== word[j].toLowerCase) { + return false + } else if (i === j) { + return true + } + i++ + j-- + } +} + +function anagramas(word1, word2) { + let i = 0 + while (word2.includes(word1[i]) && word1.length === word2.length) { + // recorre la primer palabra verificando que la segunda contenga el caracter y remplaza a este por un guion + // para matener la igual de length y evitar que verifique con el mismo caracter dos veces + if (i === word1.length - 1) return true + word2 = word2.replace(word1[i], '-') + i++ + } return false +} + +function isogramas(word) { + let i = 0 + do { + // recorre la palabra guardando letra por letra y cuando quita una, + // la remplaza por un guion y verifica que no esta repetida + if (i === word.length - 1) return true + letter = word[i] + word = word.replace(word[i], '-') + i++ + } while (!word.includes(letter)); + return false +} + +function startProgram() { + // ingresa la/s palabra/s a la función pertinente, esta devuelve true | false y tiene una frase especifica para cada valor + let operation = prompt('Que deseas verificar si es/son palindromos, anagramas o isogramas?') + let word = 'y' + if (operation.toLowerCase() === 'palindromos' || operation.toLowerCase() === 'palindromo') { + while (word.toLowerCase() !== 'n') { + if (word.toLowerCase() === 'y'|| word.toLowerCase() === 's') { + word = prompt('Ingrese la palabra') + word = prompt(`La palabra ${word} ${palindromos(word) ? 'es un palíndromo' : 'no es un palíndromo'}` + "\n".repeat(2) + + `Desea comprobar si otra palabra es un palíndromo? Y/N`) + } else { + word = prompt('Desea comprobar si otra palabra es un palíndromo? Y/N') + } + } + } else if (operation.toLowerCase() === 'anagramas' || operation.toLowerCase() === 'anagrama') { + while (word.toLowerCase() !== 'n') { + if (word.toLowerCase() === 'y'|| word.toLowerCase() === 's') { + word = prompt('Ingrese la primer palabra') + let word2 = prompt('Ingrese la segunda palabra') + word = prompt(`Las palabras ${word} y ${word2} ${anagramas(word, word2) ? 'son anagramas' : 'no son anagramas'}` + "\n".repeat(2) + + `Desea comprobar si otras palabras son anagramas? Y/N`) + } else { + word = prompt('Desea comprobar si otras palabras son anagramas? Y/N') + } + } + } else if (operation.toLowerCase() === 'isogramas' || operation.toLowerCase() === 'isograma') { + while (word.toLowerCase() !== 'n') { + if (word.toLowerCase() === 'y'|| word.toLowerCase() === 's') { + word = prompt('Ingrese la palabra') + word = prompt(`La palabra ${word} ${isogramas(word) ? 'es un isograma' : 'no es un isograma'}` + "\n".repeat(2) + + `Desea comprobar si otra palabra es un isograma? Y/N`) + } else { + word = prompt('Desea comprobar si otra palabra es un isograma? Y/N') + } + } + } + do { + // bucle para saber si el usuario quiere hacer otra operacion (si no ingresa 's', 'y' o 'n') se repite hasta que ingrese un valor aceptado + operation = prompt('Deseas hacer otra operación? Y/N') + if (operation.toLowerCase() === 'y'|| operation.toLowerCase() === 's') startProgram() + } while (operation.toLowerCase() !== 'n') +} +startProgram() \ No newline at end of file diff --git a/Roadmap/05 - VALOR Y REFERENCIA/javascript/pedamoci.js b/Roadmap/05 - VALOR Y REFERENCIA/javascript/pedamoci.js new file mode 100644 index 0000000000..a9ffe41c9f --- /dev/null +++ b/Roadmap/05 - VALOR Y REFERENCIA/javascript/pedamoci.js @@ -0,0 +1,70 @@ +// ------------------------- ASIGNACION DE VARIABLES ------------------------- + /* --> variables con valores primitivos <-- */ + let varValorNumber = 123 + let varValorStrig = 'string' + let varValorBoolean = true + let varValorUndefined = undefined + let varValorNull = null + + // POR VALOR --> se copia el valor de una variable (tiene que contener un dato primitivo) a otra + let asignacionValorNumber = varValorNumber + let asignacionValorString = varValorStrig + let asignacionValorBoolean = varValorBoolean + let asignacionValorUndefined = varValorUndefined + let asignacionValorNull = varValorNull + // cada variable 'asignacion' contiene copia del valor que contiene la variable original + + /* --> variables con valores tipo objeto<--*/ + let varTOArray = [12, 'messi', true, 98567] + let varTOObjeto = {'messi': 'futbolista', 'Del Potro': 'tenista', 'Hamilton': 'Piloto'} + let varTOFuncion = function saludar() { + console.log('Hola') + } + + // POR REFERENCIA --> se copia la referencia a un valor almacenado en memoria + let asignacionReferenciaArray = varTOArray + let asignacionReferenciaObjeto = varTOObjeto + let asignacionReferenciaFuncion = varTOFuncion + +// ------------------------- EJEMPLOS DE FUNCIONES CON VARIABLES ------------------------- + // POR VALOR + function modificarVarXValor(valorNum) { + valorNum = 852 + console.log('valor de la variable dentro de la función: ' + valorNum) + } + console.log('valor de la variable antes de ingresar a la función: ' + asignacionValorNumber) + modificarVarXValor(asignacionValorNumber) + console.log('valor de la variable despues de ingresar a la función: ' + asignacionValorNumber) + + // POR REFERENCIA + function modificarVarXReferencia(valorArr) { + valorArr.push('dato ingresado dentro de la funcion') + console.log('valor de la variable dentro de la función: ' + valorArr) + } + console.log('valor de la variable antes de ingresar a la función: ' + asignacionReferenciaArray) + modificarVarXReferencia(asignacionReferenciaArray) + console.log('valor de la variable despues de ingresar a la función: ' + asignacionReferenciaArray) + // la variable se modifica fuera de la funcion ya que al ingresar como dato un array en verdad lo que hace es ingresar la ubicacion en memoria del array original y ese es el que modifica el push que esta adentro de la funcion + +// ----------------------------------- DIFICULTAD EXTRA ----------------------------------- +// INTERCAMBIO DE PARAMETROS POR VALOR +let parametroValor1 = 5 +let parametroValor2 = 8 +function intercambiarXValor(v1, v2) { + return [v2, v1] +} +let [intercambiadoValor1, intercambiadoValor2] = intercambiarXValor(parametroValor1, parametroValor2) +console.log(`El valor original 1 es: ${parametroValor1} y el 2 es: ${parametroValor2}` + "\n" + `El valor intercambiado del 1 es: ${intercambiadoValor1} y del 2 es: ${intercambiadoValor2}`) + + +// INTERCAMBIO DE PARAMETROS POR REFERENCIA +let parametroReferencia1 = [5, 6454, 324, 2, 878] +let parametroReferencia2 = ['jaime', 'pepe', 'juan', 'jesus', 'hector'] +function intercambiarXReferencia(v1, v2) { + let valorIntercambiador = [...v1] + v1 = [...v2] + v2 = [...valorIntercambiador] + return [v1, v2] +} +let [intercambiadoReferencia1, intercambiadoReferencia2] = intercambiarXReferencia(parametroReferencia1, parametroReferencia2) +console.log(`El valor original 1 es: ${parametroReferencia1} y el 2 es: ${parametroReferencia2}` + "\n" + `El valor intercambiado del 1 es: ${intercambiadoReferencia1} y del 2 es: ${intercambiadoReferencia2}`) \ No newline at end of file diff --git a/Roadmap/06 - RECURSIVIDAD/javascript/pedamoci.js b/Roadmap/06 - RECURSIVIDAD/javascript/pedamoci.js new file mode 100644 index 0000000000..47264a8989 --- /dev/null +++ b/Roadmap/06 - RECURSIVIDAD/javascript/pedamoci.js @@ -0,0 +1,59 @@ +// ------------------------------- EJERCICIO ------------------------------- +// function recursiva(cant) { +// let i = cant +// if (i >= 0){ +// console.log(i) +// i-- +// recursiva(i) +// } +// } +// recursiva(100) + +// ---------------------------- DIFICULTAD EXTRA ---------------------------- +let vFactorial = 0 +function factorial(num) { + vFactorial = vFactorial + num + num-- + if (num !== 0 ) { + factorial(num) + } +} + +let posicion = 0 +let default1 = 0 +let default2 = 1 +function fibonacci(pos) { + if (posicion !== pos) { + posicion++ + (posicion % 2 === 0) ? default2 = default1 + default2 + : default1 = default1 + default2 + fibonacci(pos) + } +} + +function calcular() { + let operation = prompt('Que desea calcular factorial o fibonacci').toLowerCase() + do { + if (operation === 'y'|| operation === 's') operation = prompt('Que desea calcular factorial o fibonacci').toLowerCase() + switch (operation) { + case 'factorial': + let num = prompt('Ingrese el valor del que desee calcular el factorial') + factorial(parseInt(num)) + alert(`El valor de ${num}! es: ${vFactorial}`) + break; + case 'fibonacci': + let pos = prompt('Ingrese la posición de fibonacci que desea averiguar (la secuencia inicia con los valores 0 y 1)' + "\n" + + `posición 1 = 1 --> (0 + 1)` + "\n" + `posición 2 = 2 --> (1 + 1) ` + "\n" + + `posición 3 = 3 --> (2 + 1)` + "\n" + `posición 4 = 5 --> (3 + 2)` + ) + fibonacci(parseInt(pos)) + alert(`El valor de fibonacci de la posicion ${pos} es ${ pos % 2 === 0 ? default2 : default1}`) + break; + default: + alert('Operación no valida') + break; + } + operation = prompt('Deseas hacer otra operación? Y/N').toLowerCase() + } while (operation !== 'n') +} +calcular() \ No newline at end of file diff --git a/Roadmap/07 - PILAS Y COLAS/javascript/pedamoci.js b/Roadmap/07 - PILAS Y COLAS/javascript/pedamoci.js new file mode 100644 index 0000000000..ac02f96bdd --- /dev/null +++ b/Roadmap/07 - PILAS Y COLAS/javascript/pedamoci.js @@ -0,0 +1,82 @@ +// ------------------------------ MECANISMO DE INTRODUCCION Y RECUPERACION DE ELEMENTO ------------------------------ + // EN PILAS --> (Un elemento en ejecución (antes de que esta termine) llama a otro elemento y pausa su ejecución, una ves que este se termine de ejecutar renueva la ejecución del anterior) + let pila = [] + + pila.push("PRIMER elemento que se añade a la pila y llama al SEGUNDO") + console.table(pila) // hay un unico elemento en la pila + pila.push('SEGUNDO elemento que se añade a la pila llamado por el PRIMERO y llama al TERCERO') + console.table(pila) // se le añade un segundo elemento a la pila + pila.push('TERCER elemento que se añade a la pila llamado por el SEGUNDO') + console.table(pila) // ya hay tres elementos en la pila + + console.log('Ejecución del ULTIMO elemento llamado a la pila: ' + pila[pila.length - 1]) // (pila.length - 1) --> para demostrar que se ejecuta el último elemento + pila.pop() // El último elemento llamado a la pila por el segundo ya se ejecuto y finalizo por lo tanto se elimina de esta + + console.log('Ejecución del SEGUNDO elemento llamado a la pila: ' + pila[pila.length - 1]) + pila.pop() // El segundo elemento llamado a la pila por el primero ya se ejecuto y finalizo por lo tanto se elimina de esta + + console.log('Ejecución del PRIMER elemento llamado a la pila, última en este caso: ' + pila[pila.length - 1]) + pila.pop() // El primer elemento llamado a la pila ya se ejecuto y finalizo por lo tanto se elimina de esta quedando vacia + + console.table(pila) // ya no hay elementos en la pila + + // EN COLAS --> (Un elemento en ejecución llama a otro elemento, cuando la ejecución del primer elemento termina recien ahí arranca la ejecución del segundo elemento) + let cola = [] + + cola.push("PRIMER elemento que se ejecuta, llama un SEGUNDO y despues un TERCERO") + console.table(cola) // hay un unico elemento en la cola + cola.push('SEGUNDO elemento que se añade a la cola llamado por el PRIMERO') + console.table(cola) // se le añade un segundo elemento a la cola + cola.push('TERCER elemento que se añade a la cola llamado por el PRIMERO') + console.table(cola) // ya hay tres elementos en la cola + + console.log('Ejecución del PRIMER elemento en la cola: ' + cola[0]) + cola.shift() // El primer elemento de la cola ya se ejecuto y finalizo por lo tanto se elimina de esta + + console.log('Ejecución del SEGUNDO elemento en la cola: ' + cola[0]) + cola.shift() // al finalizar la ejecución del primer elemento inicia la del segundo. Este se ejecuta y una vez finaliza se elimina de la cola + + console.log('Ejecución del TERCER elemento en la cola, última en este caso: ' + cola[0]) + cola.shift() // al finalizar la ejecución del segundo elemento inicia la del tercero. Este se ejecuta y una vez finaliza se elimina de la cola quedando esta vacia + + console.table(cola) // ya no hay elementos en la cola + +// ---------------------------------- DIFICULTAD EXTRA ---------------------------------- +function navegadorWeb() { + let pagina = [] + let move = '' + do { + move = prompt((pagina.length === 0 ? " ".repeat(31) + `Bienvenidos a la página de incio` + " ".repeat(31) + : " ".repeat(30) + `Bienvenidos a la página número ${pagina.length}` + " ".repeat(30)) + + + "\n" + " ".repeat(22) + "(esbribe exit/salir para terminar la ejecución)" + " ".repeat(21) + "\n".repeat(4) + + "<--(atras/back)" + " ".repeat(19) + "Desea ir hacia" + " ".repeat(19) + "(next/adelante)-->").toLowerCase() + if (move === 'adelante' || move === 'next') { + pagina.push('new page') + } else if ((move === 'atras' || move === 'back') && pagina.length !==0) { + pagina.pop() + } + } while (move !== 'salir' && move !== 'exit'); +} +navegadorWeb() + +function impresora() { + let colaDocumentos = [] + let documento = '' + do { + documento = prompt(" ".repeat(47) + "IMPRESORA" + " ".repeat(48) + "\n" + + " ".repeat(14) + "Escriba el nombre del documento que desea imprimir" + " ".repeat(14) + "\n" + + " ".repeat(34) + `(en cola hay ${colaDocumentos.length} documentos)` + " ".repeat(34) + "\n".repeat(4) + + " ".repeat(19) + "Escriba 'imprimir' para imprimir un documento" + " ".repeat(20)).toLowerCase() + if (documento === 'imprimir' && colaDocumentos.length !== 0) { + alert(" ".repeat(47) + "IMPRESORA" + " ".repeat(48) + "\n".repeat(3) + + "Se ha impreso: " + colaDocumentos[0] + ".pdf") + colaDocumentos.shift() + } else if (documento !== 'imprimir') { + colaDocumentos.push(documento) + alert(" ".repeat(47) + "IMPRESORA" + " ".repeat(48) + "\n".repeat(3) + + "Se ha agregado a la cola: " + documento + ".pdf") + } + } while (true); +} +impresora() \ No newline at end of file diff --git a/Roadmap/08 - CLASES/javascript/pedamoci.js b/Roadmap/08 - CLASES/javascript/pedamoci.js new file mode 100644 index 0000000000..119cf56e59 --- /dev/null +++ b/Roadmap/08 - CLASES/javascript/pedamoci.js @@ -0,0 +1,142 @@ +class Pokemon { + name // <--- atributo + primerTipo // <--- atributo + segundoTipo // <--- atributo + + constructor(name, primerTipo, segundoTipo) { // <--- inicializador + this.name = name + this.primerTipo = primerTipo + this.segundoTipo = segundoTipo + } + + imprimirAtributos() { // <--- función que imprime los atributos + console.log(`${this.name} es de tipo ${this.primerTipo} y ${this.segundoTipo}`) + } + + /*imprimirAtributos(name) { // <--- función que imprime los atributos + Object.entries(name).forEach(([key, value]) => { + console.log(`${key}: ${value}`) + }) + //console.log(`${this.name} es de tipo ${this.primerTipo} y ${this.segundoTipo}`) + }*/ +} + +const dartix = new Pokemon('Dartix', 'Planta', 'Volador') // <--- crandola y estableciendo sus parametros +dartix.imprimirAtributos() + +/*dartix.imprimirAtributos(dartix)*/ + +dartix.name = 'Decidueye' // <--- modificando sus parametros +dartix.segundoTipo = 'Fantasma' // <--- modificando sus parametros +dartix.imprimirAtributos() // <--- imprimiendo los parametros con la función dentro de la clase + +/*dartix.imprimirAtributos(dartix)*/ + +// ----------------------------------------- DIFICULTAD EXTRA ----------------------------------------- + // CLASE REPRESENTANDO ESTRUCTURA DE PILA + class Pila { + constructor(name) { + this.namePila = name + this.pila = [] + } + + add(name) { + this.pila.push(name) + console.log(`Se ha añadido a la pila el elemento '${name}'`) + } + + delete(name) { + if (this.pila.length === 0) { + console.log('La pila esta vacia') + } else if (name === undefined) { + this.pila.pop() + console.log('Ultimo elemento de la pila eliminado') + } else if (this.pila.includes(name)) { + let index = this.pila.lastIndexOf(name) // <--- obtiene en el array la posición del elemento que se quiere eleminar + let lastElementPila = this.pila.slice(index + 1) // <--- guarda los elementos que hay despues del que se desea eliminar + this.pila = this.pila.slice(0, index).concat(lastElementPila) // <--- corta el array original hasta el elemento que se quiere eliminar (no incluido) y se le añade el array con los elemntos guardados + console.log(`se ha eliminado ${name} de la pila`) + } else { + console.log(`No hay elementos con el nombre: '${name}' en la pila`) + } + } + + numberElements() { + console.log(`Hay ${this.pila.length} elementos en la pila`) + } + + printAll() { + while (this.pila.length !== 0) { + console.log(`Se a impreso el elemento ${this.pila[this.pila.length - 1]}`) + this.pila.pop() + } + console.log('La pila esta vacia') + } + } + + const nuevaPila = new Pila('primera pila') + console.log(nuevaPila) + + // añade elementos + nuevaPila.add('pepe'); nuevaPila.add('jaime'); nuevaPila.add('juan'); nuevaPila.add('pedro'); nuevaPila.add('luffy'); nuevaPila.add('deadpool'); nuevaPila.add('red'); nuevaPila. add('aang'); nuevaPila.add('homero'); nuevaPila.add('spiderman'); nuevaPila.numberElements() + + nuevaPila.delete('zoro') // <--- intento de borrar elemento no existente + nuevaPila.delete('red') // <--- borrar elemento existente por nombre + nuevaPila.delete() // <--- borrar último elemento + + nuevaPila.numberElements() + nuevaPila.printAll() + + // CLASE REPRESENTANDO ESTRUCTURA DE COLA + class Cola { + constructor(name) { + this.nameCola = name + this.cola = [] + } + + add(name) { + this.cola.push(name) + console.log(`Se ha añadido a la cola el elemento '${name}'`) + } + + delete(name) { + if (this.cola.length === 0) { + console.log('La cola esta vacia') + } else if (name === undefined) { + this.cola.shift() + console.log('Primer elemento de la cola eliminado') + } else if (this.cola.includes(name)) { + let index = this.cola.lastIndexOf(name) // <--- obtiene en el array la posición del elemento que se quiere eleminar + let lastElementCola = this.cola.slice(index + 1) // <--- guarda los elementos que hay despues del que se desea eliminar + this.cola = this.cola.slice(0, index).concat(lastElementCola) // <--- corta el array original hasta el elemento que se quiere eliminar (no incluido) y se le añade el array con los elemntos guardados + console.log(`se ha eliminado ${name} de la cola`) + } else { + console.log(`No hay elementos con el nombre: '${name}' en la cola`) + } + } + + numberElements() { + console.log(`Hay ${this.cola.length} elementos en la cola`) + } + + printAll() { + while (this.cola.length !== 0) { + console.log(`Se a impreso el elemento ${this.cola[0]}`) + this.cola.shift() + } + console.log('La pila esta vacia') + } + } + + const nuevaCola = new Cola('primera cola') + console.log(nuevaCola) + + // añade elementos + nuevaCola.add('pepe'); nuevaCola.add('jaime'); nuevaCola.add('juan'); nuevaCola.add('pedro'); nuevaCola.add('luffy'); nuevaCola.add('deadpool'); nuevaCola.add('red'); nuevaCola. add('aang'); nuevaCola.add('homero'); nuevaCola.add('spiderman'); nuevaCola.numberElements() + + nuevaCola.delete('zoro') // <--- intento de borrar elemento no existente + nuevaCola.delete('red') // <--- borrar elemento existente por nombre + nuevaCola.delete() // <--- borrar último elemento + + nuevaCola.numberElements() + nuevaCola.printAll() \ No newline at end of file diff --git a/Roadmap/09 - HERENCIA/javascript/pedamoci.js b/Roadmap/09 - HERENCIA/javascript/pedamoci.js new file mode 100644 index 0000000000..abb32ec735 --- /dev/null +++ b/Roadmap/09 - HERENCIA/javascript/pedamoci.js @@ -0,0 +1,119 @@ +class Animal { + constructor(name) { + this.name = name + } + hablar(modo){ + console.log(modo) + } +} + +class Perro extends Animal { + constructor(name){ + super(name) + } + ladrar() { + this.hablar('guau') + } +} + +class Gato extends Animal { + constructor(name){ + super(name) + } + maullar() { + this.hablar('miau') + } +} + +const perro = new Perro('Teo') +const gato = new Gato('Cleopatra') + +perro.ladrar() +gato.maullar() + +// ------------------------------------ DIFICULTAD EXTRA ------------------------------------ +class Empleado { + constructor(id, name) { + this.id = id + this.name = name + this.subordinados = [] + } + + agregarSubordinado(empleado) { + this.subordinados.push(empleado) + } +} +class Gerente extends Empleado { + constructor(id, name) { + super(id, name) + } + + asingProycet(manager, proyect) { + console.log(`${this.name} le ha asignado a ${manager.name} el proyecto ${proyect}`) + } +} + +class ProjectManager extends Empleado { + constructor(id, name, gerente) { + super(id, name) + gerente.agregarSubordinado(this) + } + + asignTaskProgramador(programador, tarea) { + console.log(`${this.name} le ha asignado a ${programador.name} programar ${tarea}`) + programador.programar(tarea) + } +} + +class Programador extends Empleado { + constructor(id, name, manager) { + super(id, name) + manager.agregarSubordinado(this) + } + + programar(tarea) { + console.log(`Empezando a programar ${tarea}`) + console.log(`${this.name} ha teminado de programar ${tarea}`) + } +} + +const gerente1 = new Gerente(1, "Gerardo") +const gerente2 = new Gerente(2, "Alfredo") +const gerente3 = new Gerente(3, "Jaime") + +const pm1 = new ProjectManager(10, "Laura", gerente1) +const pm2 = new ProjectManager(20, "Roberto", gerente1) +const pm3 = new ProjectManager(30, "Walter", gerente2) +const pm4 = new ProjectManager(40, "Sofía", gerente2) +const pm5 = new ProjectManager(50, "Carmela", gerente3) +const pm6 = new ProjectManager(60, "Bautista", gerente3) + + +const programador1 = new Programador(100, 'Juan', pm1) +const programador2 = new Programador(200, 'Mauricio', pm1) +const programador3 = new Programador(300, 'Federico', pm2) +const programador4 = new Programador(400, 'Baltazar', pm2) +const programador5 = new Programador(500, 'Sergio', pm3) +const programador6 = new Programador(600, 'Dario', pm3) +const programador7 = new Programador(700, 'Manuel', pm4) +const programador8 = new Programador(800, 'Raul', pm4) +const programador9 = new Programador(900, 'Horacio', pm5) +const programador10 = new Programador(1000, 'Tomas', pm5) +const programador11 = new Programador(1100, 'Carlos', pm6) +const programador12 = new Programador(1200, 'Francisco', pm6) + +// Proyect manger le asigna una tarea a un programador y este la realiza +pm1.asignTaskProgramador(programador1, 'Página web') + +// Gerente le asigna un proyecto a un proyect manager +gerente2.asingProycet(pm4, 'silksong') + + +// Programador programa +programador12.programar('ToDo') + +console.log(`El gerente ${gerente1.name} tiene de subordinados a ${gerente1.subordinados[0].name} y a ${gerente1.subordinados[1].name}, ${gerente1.subordinados[0].name} tiene como subordinados a ${gerente1.subordinados[0].subordinados[0].name} y a ${gerente1.subordinados[0].subordinados[1].name} y ${gerente1.subordinados[1].name} tiene como subordinados a ${gerente1.subordinados[1].subordinados[0].name} y a ${gerente1.subordinados[1].subordinados[1].name}`) + +console.log(`El gerente ${gerente2.name} tiene de subordinados a ${gerente2.subordinados[0].name} y a ${gerente2.subordinados[1].name}, ${gerente2.subordinados[0].name} tiene como subordinados a ${gerente2.subordinados[0].subordinados[0].name} y a ${gerente2.subordinados[0].subordinados[1].name} y ${gerente2.subordinados[1].name} tiene como subordinados a ${gerente2.subordinados[1].subordinados[0].name} y a ${gerente2.subordinados[1].subordinados[1].name}`) + +console.log(`El gerente ${gerente3.name} tiene de subordinados a ${gerente3.subordinados[0].name} y a ${gerente3.subordinados[1].name}, ${gerente3.subordinados[0].name} tiene como subordinados a ${gerente3.subordinados[0].subordinados[0].name} y a ${gerente3.subordinados[0].subordinados[1].name} y ${gerente3.subordinados[1].name} tiene como subordinados a ${gerente3.subordinados[1].subordinados[0].name} y a ${gerente3.subordinados[1].subordinados[1].name}`) \ No newline at end of file