diff --git a/.gitignore b/.gitignore index 7e6a3b796..53e6c00ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ - +.vscode # Created by https://www.toptal.com/developers/gitignore/api/android,androidstudio,kotlin # Edit at https://www.toptal.com/developers/gitignore?templates=android,androidstudio,kotlin diff --git a/soluciones-javascript/01-fizzbuzz/app.js b/soluciones-javascript/01-fizzbuzz/app.js new file mode 100644 index 000000000..98dabb19c --- /dev/null +++ b/soluciones-javascript/01-fizzbuzz/app.js @@ -0,0 +1,29 @@ +/* + *#1 EL FAMOSO "FIZZ BUZZ"* + *** + * Escribe un programa que muestre por consola (con un print) los + * números de 1 a 100 (ambos incluidos y con un salto de línea entre + * cada impresión), sustituyendo los siguientes: + * - Múltiplos de 3 por la palabra "fizz". + * - Múltiplos de 5 por la palabra "buzz". + * - Múltiplos de 3 y de 5 a la vez por la palabra "fizzbuzz". + */ +const fizzBuzz = () => { + + for (let i = 1; i <= 100; i++) { + + if(i % 3 === 0 && i % 5 === 0){ + console.log("fizzbuzz"); + }else if (i % 3 === 0) { + console.log("fizz"); + }else if( i % 5 === 0){ + console.log("buzz"); + }else{ + console.log(i); + } + + } + +} + +fizzBuzz(); \ No newline at end of file diff --git a/soluciones-javascript/02-anagrama/app.js b/soluciones-javascript/02-anagrama/app.js new file mode 100644 index 000000000..5fe643f09 --- /dev/null +++ b/soluciones-javascript/02-anagrama/app.js @@ -0,0 +1,40 @@ +/* + * Escribe una función que reciba dos palabras (String) y retorne + * verdadero o falso (Bool) según sean o no anagramas. + * - Un Anagrama consiste en formar una palabra reordenando TODAS + * las letras de otra palabra inicial. + * - NO hace falta comprobar que ambas palabras existan. + * - Dos palabras exactamente iguales no son anagrama. + */ + +const isAnagram = (string1 = '', string2 = '') => { + + //Si algún String está vacío retorna false + if(!string1 || !string2 ) return false; + + if(string1.length !== string2.length ) return false; + + const stringLowerCase1 = string1.toLowerCase().trim(); + const stringLowerCase2 = string2.toLowerCase().trim(); + + //Si las palabras son exactamente iguales retorna false + if(stringLowerCase1 === stringLowerCase2) return false; + + const arrayString1 = stringLowerCase1.split("").sort().join(''); + const arrayString2 = stringLowerCase2.split("").sort().join(''); + + return arrayString1 === arrayString2; + +} + + +console.log("Es un anagrama (amor + roma): " + isAnagram("amor", "roma")); +console.log("Es un anagrama (listen + silent): " + isAnagram("listen", "silent")); +console.log("Es un anagrama (test + test): " + isAnagram("test", "test")); +console.log("Es un anagrama ( + word): " + isAnagram("", "word")); +console.log("Es un anagrama (test + testing): " + isAnagram("test", "testing")); +console.log("Es un anagrama (Listen + Silent): " + isAnagram("Listen", "Silent")); +console.log("Es un anagrama (Dormitory + Dirty room): " + isAnagram("Dormitory", "Dirty room")); + + + diff --git a/soluciones-javascript/03-fibonacci/app.js b/soluciones-javascript/03-fibonacci/app.js new file mode 100644 index 000000000..6777a9940 --- /dev/null +++ b/soluciones-javascript/03-fibonacci/app.js @@ -0,0 +1,33 @@ +/* + * * LA SUCESIÓN DE FIBONACCI * + * Escribe un programa que imprima los 50 primeros números de la sucesión + * de Fibonacci empezando en 0. + * - La serie Fibonacci se compone por una sucesión de números en + * la que el siguiente siempre es la suma de los dos anteriores. + * 0, 1, 1, 2, 3, 5, 8, 13... + */ + + +const sucesionFibonacci = ( cantidadNumeros ) => { + + if ( cantidadNumeros < 0 ) return console.log(0); + + let anterior = 0; + let actual = 1; + + for (let i = 0; i < cantidadNumeros; i++) { + + console.log(`${ i + 1 }_: ${anterior}`); + + let temp = anterior; + anterior = actual + anterior; + actual = temp; + + } + + +} + + + +sucesionFibonacci( 50 ); diff --git a/soluciones-javascript/04-numero-primo/app.js b/soluciones-javascript/04-numero-primo/app.js new file mode 100644 index 000000000..0d230afa6 --- /dev/null +++ b/soluciones-javascript/04-numero-primo/app.js @@ -0,0 +1,24 @@ +/* + * Escribe un programa que se encargue de comprobar si un número es o no primo. + * Hecho esto, imprime los números primos entre 1 y 100. + */ + +const esNumeroPrimo = (numero) => { + if (numero <= 1) return false; + + if (numero === 2) return true; + + for (let i = 2; i <= Math.sqrt(numero); i++) { + if (numero % i === 0) { + return false; + } + } + + return true; +}; + +for (let i = 2; i < 100; i++) { + if (esNumeroPrimo(i)) { + console.log(i); + } +} diff --git a/soluciones-javascript/05-area-poligono/app.js b/soluciones-javascript/05-area-poligono/app.js new file mode 100644 index 000000000..0fdb4d323 --- /dev/null +++ b/soluciones-javascript/05-area-poligono/app.js @@ -0,0 +1,41 @@ +/* + * Crea una única función (importante que sólo sea una) que sea capaz + * de calcular y retornar el área de un polígono. + * - La función recibirá por parámetro sólo UN polígono a la vez. + * - Los polígonos soportados serán Triángulo, Cuadrado y Rectángulo. + * - Imprime el cálculo del área de un polígono de cada tipo. + */ + +const areaPoligono = ({ tipo = "", datosPoligono = {} }) => { + + const esPositivo = (n) => typeof n === 'number' && n > 0; + + switch (tipo) { + case "Triangulo": + if ( esPositivo(datosPoligono.base) && esPositivo(datosPoligono.altura) ) { + return (datosPoligono.base * datosPoligono.altura) / 2; + }else{ + throw new Error("Los datos del triangulo deben ser positivos"); + } + case "Cuadrado": + if ( esPositivo(datosPoligono.lado) ) { + return datosPoligono.lado * datosPoligono.lado; + }else{ + throw new Error("Los datos del Cuadrado deben ser positivos"); + } + case "Rectangulo": + if ( esPositivo(datosPoligono.base) && esPositivo(datosPoligono.altura) ) { + return datosPoligono.base * datosPoligono.altura; + }else{ + throw new Error("Los datos del Rectangulo deben ser positivos"); + } + default: + throw new Error("Especifica un dato correcto"); + } + +} + +// Ejemplos de uso +console.log(areaPoligono({ tipo: "Triangulo", datosPoligono: { base: 2, altura: 4 } })); +console.log(areaPoligono({ tipo: "Cuadrado", datosPoligono: { lado: 5 } })); +console.log(areaPoligono({ tipo: "Rectangulo", datosPoligono: { base: 3, altura: 6 } })); \ No newline at end of file diff --git a/soluciones-javascript/06-aspect-ratio-image/app.js b/soluciones-javascript/06-aspect-ratio-image/app.js new file mode 100644 index 000000000..fce15cbc0 --- /dev/null +++ b/soluciones-javascript/06-aspect-ratio-image/app.js @@ -0,0 +1,43 @@ +/* + * Crea un programa que se encargue de calcular el aspect ratio de una + * imagen a partir de una url. + * - Url de ejemplo: + * https://es.vitejs.dev/og-image-announcing-vite3.png + * - Por ratio hacemos referencia por ejemplo a los "16:9" de una + * imagen de 1920*1080px. + */ + + +const calcularAspectRatio = async (url) => { + + const img = new Image(); + + img.src = url; + + img.onload = () => { + const width = img.width; + const height = img.height; + + // Maximo comun divisor + const mcd = ( a, b ) => b === 0 ? a : mcd( b, a % b ); + + console.log(mcd(width, height)); + + const ratioMCD = mcd(width, height); + + console.log(`La resolución de la imagen es ${width}x${height}`); + console.log(`La relación de aspecto es: ${ width / ratioMCD }:${ height / ratioMCD }`); + + + } + + img.onerror = () => { + console.error('No se pudo cargar la imagen'); + } + + return img; + +} + +const url = "https://cdn.unotv.com/images/2024/03/mazapan-perrito-influencer-143900-1024x576.jpeg" +calcularAspectRatio(url); \ No newline at end of file diff --git a/soluciones-javascript/06-aspect-ratio-image/index.html b/soluciones-javascript/06-aspect-ratio-image/index.html new file mode 100644 index 000000000..916bfeafc --- /dev/null +++ b/soluciones-javascript/06-aspect-ratio-image/index.html @@ -0,0 +1,11 @@ + + + + + + Ejercicio de programación + + + + + \ No newline at end of file diff --git a/soluciones-javascript/07-inviertiendo-cadenas/app.js b/soluciones-javascript/07-inviertiendo-cadenas/app.js new file mode 100644 index 000000000..8ece70480 --- /dev/null +++ b/soluciones-javascript/07-inviertiendo-cadenas/app.js @@ -0,0 +1,22 @@ +/* + * Crea un programa que invierta el orden de una cadena de texto + * sin usar funciones propias del lenguaje que lo hagan de forma automática. + * - Si le pasamos "Hola mundo" nos retornaría "odnum aloH" + */ + +const reverseTextString = (string) => { + + const stringFormatter = string.trim(); + let reverseText = ""; + + for (let i = 1; i <= stringFormatter.length; i++) { + + reverseText += stringFormatter[ stringFormatter.length - i]; + + } + + return reverseText; + +} + +console.log(reverseTextString(" Hola Mundo ")); \ No newline at end of file diff --git a/soluciones-javascript/07-inviertiendo-cadenas/index.html b/soluciones-javascript/07-inviertiendo-cadenas/index.html new file mode 100644 index 000000000..5a798babe --- /dev/null +++ b/soluciones-javascript/07-inviertiendo-cadenas/index.html @@ -0,0 +1,11 @@ + + + + + + Invirtiendo cadenas + + + + + \ No newline at end of file diff --git a/soluciones-javascript/08-contando-palabras/app.js b/soluciones-javascript/08-contando-palabras/app.js new file mode 100644 index 000000000..1bfbb36d1 --- /dev/null +++ b/soluciones-javascript/08-contando-palabras/app.js @@ -0,0 +1,25 @@ +/* + * Crea un programa que cuente cuantas veces se repite cada palabra + * y que muestre el recuento final de todas ellas. + * - Los signos de puntuación no forman parte de la palabra. + * - Una palabra es la misma aunque aparezca en mayúsculas y minúsculas. + * - No se pueden utilizar funciones propias del lenguaje que + * lo resuelvan automáticamente. + */ + +const countWords = (text) => { + const cleanedText = text.toLowerCase().replace(/[^\w\s]/g, ''); + + const wordsArray = cleanedText.split(/\s+/).filter( word => word !== ''); + + const wordCount = {}; + console.log({cleanedText}, {wordsArray}); + + wordsArray.forEach(word => { + wordCount[word] = (wordCount[word] || 0) + 1; + }); + + console.log( { wordsArray, wordCount } ); +}; + +countWords(" Hola, asd una páasdlabra d asd asd repetida,, hotra a a dsad sad palabraasd repetida paasdq3wrlabra o hola "); diff --git a/soluciones-javascript/08-contando-palabras/index.html b/soluciones-javascript/08-contando-palabras/index.html new file mode 100644 index 000000000..7e9e5a84d --- /dev/null +++ b/soluciones-javascript/08-contando-palabras/index.html @@ -0,0 +1,12 @@ + + + + + + Contando Palabras + + +

Abre la consola y mira el resultado

+ + + \ No newline at end of file diff --git a/soluciones-javascript/09-decimal-binario/app.js b/soluciones-javascript/09-decimal-binario/app.js new file mode 100644 index 000000000..1d0d3c7a4 --- /dev/null +++ b/soluciones-javascript/09-decimal-binario/app.js @@ -0,0 +1,20 @@ +/* + * Crea un programa se encargue de transformar un número + * decimal a binario sin utilizar funciones propias del lenguaje que lo hagan directamente. + */ + +const decimalToBinary = (number) => { + let numberBinary = []; + let numberNew = number; + + while (numberNew > 0) { + numberBinary.unshift(Math.floor(numberNew % 2)); + numberNew = Math.floor(numberNew / 2); + } + + return numberBinary.join(""); + + +}; + +console.log(decimalToBinary(10)); diff --git a/soluciones-javascript/09-decimal-binario/index.html b/soluciones-javascript/09-decimal-binario/index.html new file mode 100644 index 000000000..6e7aece82 --- /dev/null +++ b/soluciones-javascript/09-decimal-binario/index.html @@ -0,0 +1,12 @@ + + + + + + 09 Decimal a Binario + + +

Abre la consola para ver el ejercicio

+ + + \ No newline at end of file diff --git a/soluciones-javascript/10-codigo-morse/app.js b/soluciones-javascript/10-codigo-morse/app.js new file mode 100644 index 000000000..55fc38d31 --- /dev/null +++ b/soluciones-javascript/10-codigo-morse/app.js @@ -0,0 +1,32 @@ +/* + * Crea un programa que sea capaz de transformar texto natural a código + * morse y viceversa. + * - Debe detectar automáticamente de qué tipo se trata y realizar + * la conversión. + * - En morse se soporta raya "—", punto ".", un espacio " " entre letras + * o símbolos y dos espacios entre palabras " ". + * - El alfabeto morse soportado será el mostrado en + * https://es.wikipedia.org/wiki/Código_morse. + */ + +console.log({dataMorseCode}); + +const codigoMorse = (text) => { + + return text.toUpperCase().split('').map( word => { + + if(dataMorseCode[word]){ + return dataMorseCode[word] + } else if (word === " "){ + return "/"; + }else { + return ""; + } + + }).join(" "); + +} + +console.log(codigoMorse("Prueba x")); +console.log(codigoMorse("Otra prueba con diferasduhwq signficado, ayuda ´++´{}")); +console.log(codigoMorse("Me gusta la cigueña, la malta y la inmal también jaja esxs xsxsada")); \ No newline at end of file diff --git a/soluciones-javascript/10-codigo-morse/dataMorseCode.js b/soluciones-javascript/10-codigo-morse/dataMorseCode.js new file mode 100644 index 000000000..63ed31223 --- /dev/null +++ b/soluciones-javascript/10-codigo-morse/dataMorseCode.js @@ -0,0 +1,11 @@ +const dataMorseCode = { + A: ".-", B: "-...", C: "-.-.", D: "-..", + E: ".", F: "..-.", G: "--.", H: "....", + I: "..", J: ".---", K: "-.-", L: ".-..", + M: "--", N: "-.", Ñ: "--.--", O: "---", + P: ".--.", Q: "--.-", R: ".-.", S: "...", + T: "-", U: "..-", V: "...-", W: ".--", + X: "-..-", Y: "-.--", Z: "--..", + '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', + '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.' +}; diff --git a/soluciones-javascript/10-codigo-morse/index.html b/soluciones-javascript/10-codigo-morse/index.html new file mode 100644 index 000000000..a0726581e --- /dev/null +++ b/soluciones-javascript/10-codigo-morse/index.html @@ -0,0 +1,13 @@ + + + + + + Codigo morse + + +

Abre la consola y mira el resultado

+ + + + \ No newline at end of file diff --git a/soluciones-javascript/11-expresiones-equilibradas/app.js b/soluciones-javascript/11-expresiones-equilibradas/app.js new file mode 100644 index 000000000..95aa88163 --- /dev/null +++ b/soluciones-javascript/11-expresiones-equilibradas/app.js @@ -0,0 +1,48 @@ +/* + * Crea un programa que comprueba si los paréntesis, llaves y corchetes + * de una expresión están equilibrados. + * - Equilibrado significa que estos delimitadores se abren y cieran + * en orden y de forma correcta. + * - Paréntesis, llaves y corchetes son igual de prioritarios. + * No hay uno más importante que otro. + * - Expresión balanceada: { [ a * ( c + d ) ] - 5 } + * - Expresión no balanceada: { a * ( c + d ) ] - 5 } + */ + +/** + * + * @param {String} expression + */ +const isBalanced = (expression) => { + const expressionWithoutSpace = expression.replace(/\s+/g, ""); + + let stackExpr = []; + + for (let i = 0; i < expressionWithoutSpace.length; i++) { + const char = expressionWithoutSpace[i]; + + if (char === "{" || char === "[" || char === "(") { + stackExpr.push(char); + } else if (char === "}" || char === "]" || char === ")") { + if (stackExpr.length === 0) { + return false; + } + + const last = stackExpr.pop(); + + if ( + (char === "}" && last !== "{") || + (char === "]" && last !== "[") || + (char === ")" && last !== "(") + ) { + return false; + } + } + } + + return stackExpr.length === 0; +}; + +console.log(isBalanced("{ [ a * ( c + d ) ] - 5 }")); +console.log(isBalanced("{ a * ( c + d ) ] - 5 }")); +console.log(isBalanced("{ [ ((a - b) + (-4 * a)) * ( c + d ) ] - 5 }")); diff --git a/soluciones-javascript/11-expresiones-equilibradas/index.html b/soluciones-javascript/11-expresiones-equilibradas/index.html new file mode 100644 index 000000000..e1ec91e64 --- /dev/null +++ b/soluciones-javascript/11-expresiones-equilibradas/index.html @@ -0,0 +1,12 @@ + + + + + + Expresiones Equilibradas + + +

Abre la consola y mira el resultado

+ + + \ No newline at end of file diff --git a/soluciones-javascript/12-eliminando-caracteres/app.js b/soluciones-javascript/12-eliminando-caracteres/app.js new file mode 100644 index 000000000..c30537792 --- /dev/null +++ b/soluciones-javascript/12-eliminando-caracteres/app.js @@ -0,0 +1,34 @@ +/* + * Crea una función que reciba dos cadenas como parámetro (str1, str2) + * e imprima otras dos cadenas como salida (out1, out2). + * - out1 contendrá todos los caracteres presentes en la str1 pero NO + * estén presentes en str2. + * - out2 contendrá todos los caracteres presentes en la str2 pero NO + * estén presentes en str1. + */ + +/** + * Función que recibe dos cadenas de texto como entrada y genera dos nuevas cadenas como salida + * - La primera cadena de salida (`out1`) contiene los caracteres presentes en `str1` pero no en `str2`. + * - La segunda cadena de salida (`out2`) contiene los caracteres presentes en `str2` pero no en `str1`. + * @param {String} str1 Cadena de texto 1 + * @param {String} str2 Cadena de texto 2 + * @returns {{ out1: string, out2: string }} Un objeto con dos propiedades: + * - `out1`: Cadena con los caracteres exclusivos de `str1`. + * - `out2`: Cadena con los caracteres exclusivos de `str2`. + */ +const eliminandoCaracteres = ( str1, str2 ) => { + + if( str1.trim() === str2.trim() ) return `Cadenas de texto iguales: Cadena 1: ${str1} Cadena 2: ${str2}`; + + const str1Unique = [...new Set(str1)]; + const str2Unique = [...new Set(str2)]; + + const out1 = str1Unique.filter( char => !str2Unique.includes(char)).join(''); + const out2 = str2Unique.filter( char => !str1Unique.includes(char)).join(''); + + return { out1, out2 } + +} + +console.log(eliminandoCaracteres('cadena similar', 'cadena diferente')); diff --git a/soluciones-javascript/12-eliminando-caracteres/index.html b/soluciones-javascript/12-eliminando-caracteres/index.html new file mode 100644 index 000000000..e2b120f24 --- /dev/null +++ b/soluciones-javascript/12-eliminando-caracteres/index.html @@ -0,0 +1,12 @@ + + + + + + Eliminando caracteres + + +

Abre la consola y observa la magia

+ + + \ No newline at end of file diff --git a/soluciones-javascript/13-palindromo/app.js b/soluciones-javascript/13-palindromo/app.js new file mode 100644 index 000000000..63e4b1566 --- /dev/null +++ b/soluciones-javascript/13-palindromo/app.js @@ -0,0 +1,32 @@ +/* + * #13 ¿Es un Palindromo? + * Escribe una función que reciba un texto y retorne verdadero o + * falso (Boolean) según sean o no palíndromos. + * Un Palíndromo es una palabra o expresión que es igual si se lee + * de izquierda a derecha que de derecha a izquierda. + * NO se tienen en cuenta los espacios, signos de puntuación y tildes. + * Ejemplo: Ana lleva al oso la avellana. + */ + +/** + * Función para verificar si una cadena de texto es palindromo o no + * @param {String} texto + */ +const esPalindromo = ( texto ) => { + + const textoFormateado = texto + .replace(/\s+/g, "") + .split('') + .map( (char, index, array) => array[ index === 0 ? array.length - 1 : array.length - (index + 1)] ) + .join('') + .toLowerCase(); + + return textoFormateado === texto.replace(/\s+/g, "").toLocaleLowerCase(); + + +} + +console.log(esPalindromo('Ana lleva al oso la avellana')); +console.log(esPalindromo('Sé verlas al revés')); +console.log(esPalindromo('Somos o no somos')); +console.log(esPalindromo('Ana lava lana')); \ No newline at end of file diff --git a/soluciones-javascript/13-palindromo/index.html b/soluciones-javascript/13-palindromo/index.html new file mode 100644 index 000000000..0a2f567a0 --- /dev/null +++ b/soluciones-javascript/13-palindromo/index.html @@ -0,0 +1,12 @@ + + + + + + Palindromo + + +

Abre La Consola y mira el resultado

+ + + \ No newline at end of file diff --git a/soluciones-javascript/14-factorial-recursivo/app.js b/soluciones-javascript/14-factorial-recursivo/app.js new file mode 100644 index 000000000..92034e851 --- /dev/null +++ b/soluciones-javascript/14-factorial-recursivo/app.js @@ -0,0 +1,15 @@ +/* + * Escribe una función que calcule y retorne el factorial de un número dado + * de forma recursiva. + */ + +const factorial = (n) => { + + if ( n <= 0 ) return 1; + + return n * factorial( n - 1 ); + +} + +console.log(factorial(3)); +console.log(factorial(10)); \ No newline at end of file diff --git a/soluciones-javascript/14-factorial-recursivo/index.html b/soluciones-javascript/14-factorial-recursivo/index.html new file mode 100644 index 000000000..e529b155e --- /dev/null +++ b/soluciones-javascript/14-factorial-recursivo/index.html @@ -0,0 +1,12 @@ + + + + + + Factorial recursivo + + +

Abre la consola y visualiza el resultado

+ + + \ No newline at end of file diff --git a/soluciones-javascript/15-numero-de-armstrong/app.js b/soluciones-javascript/15-numero-de-armstrong/app.js new file mode 100644 index 000000000..3f5c54899 --- /dev/null +++ b/soluciones-javascript/15-numero-de-armstrong/app.js @@ -0,0 +1,28 @@ +/* + * Escribe una función que calcule si un número dado es un número de Armstrong + * (o también llamado narcisista). + * Si no conoces qué es un número de Armstrong, debes buscar información + * al respecto. + */ + +/** + * Función para calcular si un número es un número de Armstrong o no. + * @param {Number} n : number + */ +const esNumeroArmstrong = (n) => { + if (n < 0) return false; + + const formattedNumber = n.toString().split("").map(Number); + const sumNumber = formattedNumber.reduce( + (prev, current) => prev + Math.pow(current, formattedNumber.length), + 0 + ); + + return sumNumber === n; +}; + +console.log(esNumeroArmstrong(153)); // true +console.log(esNumeroArmstrong(9474)); // true +console.log(esNumeroArmstrong(9475)); // false +console.log(esNumeroArmstrong(370)); // true + diff --git a/soluciones-javascript/15-numero-de-armstrong/index.html b/soluciones-javascript/15-numero-de-armstrong/index.html new file mode 100644 index 000000000..b6c9a859a --- /dev/null +++ b/soluciones-javascript/15-numero-de-armstrong/index.html @@ -0,0 +1,12 @@ + + + + + + Ejercicio 15 + + +

Ejercicio 15 - Abre la consola

+ + + \ No newline at end of file diff --git a/soluciones-javascript/16-cuantos-dias/app.js b/soluciones-javascript/16-cuantos-dias/app.js new file mode 100644 index 000000000..b9f1ece3b --- /dev/null +++ b/soluciones-javascript/16-cuantos-dias/app.js @@ -0,0 +1,37 @@ +/* + * Crea una función que calcule y retorne cuántos días hay entre dos cadenas + * de texto que representen fechas. + * - Una cadena de texto que representa una fecha tiene el formato "dd/MM/yyyy". + * - La función recibirá dos String y retornará un Int. + * - La diferencia en días será absoluta (no importa el orden de las fechas). + * - Si una de las dos cadenas de texto no representa una fecha correcta se + * lanzará una excepción. + */ + +/** + * + * @param {String} fecha1 : 'dd/mm/yyyy' + * @param {String} fecha2 : 'dd/mm/yyyy' + */ +const cuantosDias = (fecha1, fecha2) => { + const regexFecha = /^\d{2}\/\d{2}\/\d{4}$/; + if (!regexFecha.test(fecha1) || !regexFecha.test(fecha2)) + throw new Error("El formato de fechas es erróneo"); + + const fechaFormatted1 = new Date(fecha1).getTime(); + const fechaFormatted2 = new Date(fecha2).getTime(); + + const diferenciaDeDias = + fechaFormatted1 > fechaFormatted2 + ? fechaFormatted1 - fechaFormatted2 + : fechaFormatted2 - fechaFormatted1; + const diferenciaDeDiasFormateado = diferenciaDeDias / (1000 * 60 * 60 * 24); + + return diferenciaDeDiasFormateado; +}; + +console.log(cuantosDias("04/16/2006", "12/05/2006")); // Esperado: 233 +console.log(cuantosDias("12/05/2006", "04/16/2006")); // Esperado: 233 +console.log(cuantosDias("01/01/2023", "12/31/2023")); // Esperado: 364 +console.log(cuantosDias("01/01/2024", "01/01/2024")); // Esperado: 0 +console.log(cuantosDias("12/05/2006", "04162006")); diff --git a/soluciones-javascript/16-cuantos-dias/index.html b/soluciones-javascript/16-cuantos-dias/index.html new file mode 100644 index 000000000..045010469 --- /dev/null +++ b/soluciones-javascript/16-cuantos-dias/index.html @@ -0,0 +1,12 @@ + + + + + + Cuantos días + + +

Ejercicio 16 - Abre la consola y visualiza el resultado

+ + + \ No newline at end of file diff --git a/soluciones-javascript/17-en-mayuscula/app.js b/soluciones-javascript/17-en-mayuscula/app.js new file mode 100644 index 000000000..d21572a66 --- /dev/null +++ b/soluciones-javascript/17-en-mayuscula/app.js @@ -0,0 +1,22 @@ +/* + * Crea una función que reciba un String de cualquier tipo y se encargue de + * poner en mayúscula la primera letra de cada palabra. + * - No se pueden utilizar operaciones del lenguaje que + * lo resuelvan directamente. + */ + +/** + * + * @param {String} string + * @returns + */ +const inUpperCase = (string) => { + return string.split(' ').map(word => { + const firstLetterCap = word.charAt(0).toUpperCase(); + const remainingLetters = word.slice(1); + return firstLetterCap + remainingLetters; + }).join(' ').trim(); +} + +console.log(inUpperCase('debi tirar mas algo')); +console.log(inUpperCase(" hola mundo! esto es una prueba ")); diff --git a/soluciones-javascript/17-en-mayuscula/index.html b/soluciones-javascript/17-en-mayuscula/index.html new file mode 100644 index 000000000..339870fcf --- /dev/null +++ b/soluciones-javascript/17-en-mayuscula/index.html @@ -0,0 +1,11 @@ + + + + + + En Mayuscula + + + + + \ No newline at end of file diff --git a/soluciones-javascript/18-carrera-de-obstaculos/app.js b/soluciones-javascript/18-carrera-de-obstaculos/app.js new file mode 100644 index 000000000..44b9fc5b4 --- /dev/null +++ b/soluciones-javascript/18-carrera-de-obstaculos/app.js @@ -0,0 +1,61 @@ +/* + * Crea una función que evalúe si un/a atleta ha superado correctamente una + * carrera de obstáculos. + * - La función recibirá dos parámetros: + * - Un array que sólo puede contener String con las palabras + * "run" o "jump" + * - Un String que represente la pista y sólo puede contener "_" (suelo) + * o "|" (valla) + * - La función imprimirá cómo ha finalizado la carrera: + * - Si el/a atleta hace "run" en "_" (suelo) y "jump" en "|" (valla) + * será correcto y no variará el símbolo de esa parte de la pista. + * - Si hace "jump" en "_" (suelo), se variará la pista por "x". + * - Si hace "run" en "|" (valla), se variará la pista por "/". + * - La función retornará un Boolean que indique si ha superado la carrera. + * Para ello tiene que realizar la opción correcta en cada tramo de la pista. + */ + +/** + * Función para determinar si un atleta ha superado correctamente un carrera de obstaculos + * @param {Array} acciones Array de palabras run | jump + * @param {String} pista String que contiene la pista + */ +const carreraObstaculos = ( acciones, pista ) => { + + if ( acciones.length !== pista.length ) + throw new Error("Las longitudes no coinciden"); + + if( !Array.isArray(acciones) || typeof pista !== 'string') + throw new Error("Parámetros inválidos: Se espera un array y un string"); + + let resultado = true; + let nuevaPista = ''; + + acciones.forEach(( accion, index) => { + + const tramo = pista[index]; + + if( tramo === '_' && accion === 'run' ){ + nuevaPista += tramo; + } else if ( tramo === '|' && accion === 'jump' ){ + nuevaPista += tramo; + }else if( tramo === '_' && accion === 'jump' ){ + nuevaPista += 'x'; + resultado = false; + } else if ( pista[index] === '|' && accion === 'run' ){ + nuevaPista += '/'; + resultado = false; + } else { + throw new Error("Tramo no identificado"); + } + }); + + console.log(nuevaPista); + + return resultado; + +} + +const arrayDeAcciones = ['run', 'run', 'run', 'jump', 'run', 'jump', 'jump', 'jump', 'run', 'run', 'jump', 'run',]; + +carreraObstaculos( arrayDeAcciones, '___|_|||__|_'); \ No newline at end of file diff --git a/soluciones-javascript/18-carrera-de-obstaculos/index.html b/soluciones-javascript/18-carrera-de-obstaculos/index.html new file mode 100644 index 000000000..b113331e2 --- /dev/null +++ b/soluciones-javascript/18-carrera-de-obstaculos/index.html @@ -0,0 +1,12 @@ + + + + + + Carrera de ]Obstaculos + + +

ABRE LA CONSOLA

+ + + \ No newline at end of file diff --git a/soluciones-javascript/19-tres-en-raya/app.js b/soluciones-javascript/19-tres-en-raya/app.js new file mode 100644 index 000000000..5d82f7914 --- /dev/null +++ b/soluciones-javascript/19-tres-en-raya/app.js @@ -0,0 +1,97 @@ +/* + * Crea una función que analice una matriz 3x3 compuesta por "X" y "O" + * y retorne lo siguiente: + * - "X" si han ganado las "X" + * - "O" si han ganado los "O" + * - "Empate" si ha habido un empate + * - "Nulo" si la proporción de "X", de "O", o de la matriz no es correcta. + * O si han ganado los 2. + * Nota: La matriz puede no estar totalmente cubierta. + * Se podría representar con un vacío "", por ejemplo. + */ + +/** + * Función de Tres En Raya + * @param {Array} matriz del juego por el usuario + */ +const tresEnRaya = (matriz) => { + + if ((matriz[0].length !== 3) || (matriz[1].length !== 3) || (matriz[2].length !== 3)) + return "Nulo"; + + const arrayDeResultado = [ ...matriz[0], ...matriz[1], ...matriz[2] ]; + + const combinacionesGanadoras = [ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + [0, 3, 6], + [1, 4, 7], + [2, 5, 8], + [0, 4, 8], + [2, 4, 6], + ]; + + const resultado = []; + + combinacionesGanadoras.forEach((combinacion) => { + const [ a, b, c ] = combinacion; + + if( + arrayDeResultado[a] !== " " && + arrayDeResultado[a] === arrayDeResultado[b] && + arrayDeResultado[a] === arrayDeResultado[c] + ){ + resultado.push(arrayDeResultado[a]); + } + + }); + + if ( resultado.includes('x') && resultado.includes('o')){ + return 'Nulo'; + } + + if (resultado.length === 0) { + return 'Empate'; + } + + if(resultado.length > 0){ + return resultado[0].toUpperCase(); + } + + return 'Nulo'; + +}; + +console.log( + "Gana O: " + + tresEnRaya([ + ["x", "x", "o"], + ["x", "o", " "], + ["o", " ", " "], + ]) +); +console.log( + "Gana x: " + + tresEnRaya([ + ["x", "x", "x"], + ["x", "o", "o"], + ["o", "o", "x"], + ]) +); + +console.log( + tresEnRaya([ + ["o", "o", "x"], + ["x", "x", "o"], + ["o", "o", "x"], + ]) +); + +console.log( + tresEnRaya([ + ["o", "o", "o"], + ["x", "x", "x"], + [" ", " ", ""], + ]) +); \ No newline at end of file diff --git a/soluciones-javascript/19-tres-en-raya/index.html b/soluciones-javascript/19-tres-en-raya/index.html new file mode 100644 index 000000000..b2229bbb8 --- /dev/null +++ b/soluciones-javascript/19-tres-en-raya/index.html @@ -0,0 +1,12 @@ + + + + + + Tres en raya + + +

Abre la consola y Visualiza el Resultado

+ + + \ No newline at end of file diff --git a/soluciones-javascript/20-conversor-tiempo/app.js b/soluciones-javascript/20-conversor-tiempo/app.js new file mode 100644 index 000000000..e23785be9 --- /dev/null +++ b/soluciones-javascript/20-conversor-tiempo/app.js @@ -0,0 +1,24 @@ +/* + * Crea una función que reciba días, horas, minutos y segundos (como enteros) + * y retorne su resultado en milisegundos. + */ + +const conversorTiempo = (dias, horas, minutos, segundos) => { + + if ( + typeof dias !== "number" || dias < 0 || + typeof horas !== "number" || dias < 0 || + typeof minutos !== "number" || dias < 0|| + typeof segundos !== "number" || dias < 0 + ) + throw new Error("Los datos deben ser númericos y mayor o igual a cero"); + + const diasASegundos = (((dias * 24) * 60) * 60); + const horasASegundos = ((horas * 60) * 60); + const minutosASegundos = ((minutos * 60)); + + return ( (diasASegundos + horasASegundos + minutosASegundos) * 1000 ); + +} + +console.log(conversorTiempo(1,1,1,1)); \ No newline at end of file diff --git a/soluciones-javascript/20-conversor-tiempo/index.html b/soluciones-javascript/20-conversor-tiempo/index.html new file mode 100644 index 000000000..a7195497f --- /dev/null +++ b/soluciones-javascript/20-conversor-tiempo/index.html @@ -0,0 +1,12 @@ + + + + + + Conversor de Tiempo + + +

Abre la consola y mira

+ + + \ No newline at end of file diff --git a/soluciones-javascript/21-parando-el-tiempo/app.js b/soluciones-javascript/21-parando-el-tiempo/app.js new file mode 100644 index 000000000..03449e264 --- /dev/null +++ b/soluciones-javascript/21-parando-el-tiempo/app.js @@ -0,0 +1,33 @@ +/* + * Crea una función que sume 2 números y retorne su resultado pasados + * unos segundos. + * - Recibirá por parámetros los 2 números a sumar y los segundos que + * debe tardar en finalizar su ejecución. + * - Si el lenguaje lo soporta, deberá retornar el resultado de forma + * asíncrona, es decir, sin detener la ejecución del programa principal. + * Se podría ejecutar varias veces al mismo tiempo. + */ + +/** + * Función que suma dos números y que los devuelve en cierto intervalo de tiempo + * @param {Number} num1 Numero 1 que recibe la función + * @param {Number} num2 Numero 2 que recibe la función + * @param {Number} segundosFinalizar Numero de tiempo en segundos + * @returns Resultado De numeros + */ +const parandoElTiempo = async (num1, num2, segundosFinalizar) => { + const suma = new Promise((resolve) => { + setTimeout(() => { + return resolve(num1 + num2); + }, segundosFinalizar * 1000); + }); + return await suma; +} + +parandoElTiempo(2, 3, 3).then((resultado) => + console.log(`Resultado de 2 + 3 después de 3 segundos: ${resultado}`) +); + +parandoElTiempo(5, 7, 2).then((resultado) => + console.log(`Resultado de 5 + 7 después de 2 segundos: ${resultado}`) +); \ No newline at end of file diff --git a/soluciones-javascript/21-parando-el-tiempo/index.html b/soluciones-javascript/21-parando-el-tiempo/index.html new file mode 100644 index 000000000..d659e7ea7 --- /dev/null +++ b/soluciones-javascript/21-parando-el-tiempo/index.html @@ -0,0 +1,12 @@ + + + + + + Parando el Tiempo + + +

Abre la consola y mira

+ + + \ No newline at end of file diff --git a/soluciones-javascript/22-calculadora-txt/Challenge21.txt b/soluciones-javascript/22-calculadora-txt/Challenge21.txt new file mode 100644 index 000000000..d5b2bd7c1 --- /dev/null +++ b/soluciones-javascript/22-calculadora-txt/Challenge21.txt @@ -0,0 +1,13 @@ +5 ++ +2 +- +1 +* +8 +- +15 ++ +4 +/ +2 \ No newline at end of file diff --git a/soluciones-javascript/22-calculadora-txt/index.js b/soluciones-javascript/22-calculadora-txt/index.js new file mode 100644 index 000000000..de11ee0eb --- /dev/null +++ b/soluciones-javascript/22-calculadora-txt/index.js @@ -0,0 +1,55 @@ +/* + * Lee el fichero "Challenge21.txt" incluido en el proyecto, calcula su + * resultado e imprímelo. + * - El .txt se corresponde con las entradas de una calculadora. + * - Cada línea tendrá un número o una operación representada por un + * símbolo (alternando ambos). + * - Soporta números enteros y decimales. + * - Soporta las operaciones suma "+", resta "-", multiplicación "*" + * y división "/". + * - El resultado se muestra al finalizar la lectura de la última + * línea (si el .txt es correcto). + * - Si el formato del .txt no es correcto, se indicará que no se han + * podido resolver las operaciones. + */ + +const fs = require("fs"); + +try { + const data = fs.readFileSync("./Challenge21.txt", "utf-8"); + const lines = data.split("\r\n").filter((line) => line.trim() !== ""); + + console.log({ lines }); + + let resultado = Number(lines[0]); + + for (let i = 1; i < lines.length; i += 2) { + let operacion = lines[i]; + let numero = Number(lines[i + 1]); + + if (isNaN(numero)) { + return "Error al Leer el dato"; + } + + switch (operacion) { + case "+": + resultado += numero; + break; + case "-": + resultado -= numero; + break; + case "*": + resultado *= numero; + break; + case "/": + resultado /= numero; + break; + default: + return resultado; + } + } + + console.log({ resultado }); +} catch (err) { + console.error("Error al leer el archivo:", err); +} diff --git a/soluciones-javascript/23-conjuntos/index.js b/soluciones-javascript/23-conjuntos/index.js new file mode 100644 index 000000000..91dfcb668 --- /dev/null +++ b/soluciones-javascript/23-conjuntos/index.js @@ -0,0 +1,50 @@ +/* + * Crea una función que reciba dos array, un booleano y retorne un array. + * - Si el booleano es verdadero buscará y retornará los elementos comunes + * de los dos array. + * - Si el booleano es falso buscará y retornará los elementos no comunes + * de los dos array. + * - No se pueden utilizar operaciones del lenguaje que + * lo resuelvan directamente. + */ + +/** + * Función que determina los iguales o no iguales de dos arrays dependiendo del valor del booleano + * @param {Array} arr1 Array de valores + * @param {Array} arr2 Array de valores + * @param {Boolean} boolean Variable que determina el flujo de la función + */ +const conjuntos = (arr1, arr2, boolean) => { + const resultado = []; + + if (boolean) { + for (let i = 0; i < arr1.length; i++) { + for (let j = 0; j < arr2.length; j++) { + if (arr1[i] === arr2[j]) { + if (!resultado.includes(arr1[i]) || !resultado.includes(arr2[j])) { + resultado.push(arr1[i]); + } + } + } + } + } else { + for (let i = 0; i < arr1.length; i++) { + for (let j = 0; j < arr2.length; j++) { + if (arr1[i] !== arr2[j]) { + if (!resultado.includes(arr1[i]) || !resultado.includes(arr2[j])) { + if (!arr1.includes(arr2[j]) && !resultado.includes(arr2[j])) { + resultado.push(arr2[j]); + } else if (!arr2.includes(arr1[i]) && !resultado.includes(arr1[i])) { + resultado.push(arr1[i]); + } + } + } + } + } + } + + return resultado; +}; + +console.log(conjuntos([1, 23, 4, 56, 7, 89, 10], [1, 23, 4, 5, 6, 67, 8, 1, 210, 10], true)); +console.log(conjuntos([1, 23, 4, 56, 7, 89, 10], [1, 23, 4, 5, 6, 67, 8, 1, 210, 10], false)); diff --git a/soluciones-javascript/24-maximo-comun-divisor-minimo-comun-multiplo/index.js b/soluciones-javascript/24-maximo-comun-divisor-minimo-comun-multiplo/index.js new file mode 100644 index 000000000..91612ff54 --- /dev/null +++ b/soluciones-javascript/24-maximo-comun-divisor-minimo-comun-multiplo/index.js @@ -0,0 +1,19 @@ +/* + * Crea dos funciones, una que calcule el máximo común divisor (MCD) y otra + * que calcule el mínimo común múltiplo (mcm) de dos números enteros. + * - No se pueden utilizar operaciones del lenguaje que + * lo resuelvan directamente. + */ + +const mcd = (a , b) => { + return b === 0 ? a : mcd(b, a % b); +} + +const mcm = (a , b) => { + return ( a * b ) / mcd(a,b); +} + +console.log(mcd(48, 36)); +console.log(mcd(12, 18)); +console.log(mcm(12, 18)); +console.log(mcm(48, 36)); diff --git a/soluciones-javascript/25-iteration-master/index.js b/soluciones-javascript/25-iteration-master/index.js new file mode 100644 index 000000000..6071d168d --- /dev/null +++ b/soluciones-javascript/25-iteration-master/index.js @@ -0,0 +1,44 @@ +/* + * Quiero contar del 1 al 100 de uno en uno (imprimiendo cada uno). + * ¿De cuántas maneras eres capaz de hacerlo? + * Crea el código para cada una de ellas. + */ + + +/** + * Función que imprime números de 1 al 100 + * @param {Number} forma: 1: 'for' | 2: 'while' | 3: 'Recursividad' + */ +const iterationMaster = (forma) => { + + if(forma === 1){ + + for (let i = 1; i <= 100; i++) { + console.log(i); + } + + } else if ( forma === 2 ) { + let i = 1; + while (i <= 100) { + console.log(i); + i++; + } + } else if( forma === 3 ) { + + const imprimirRecursivamente = (i = 1) => { + if ( i > 100 ) return; + console.log(i); + imprimirRecursivamente( i + 1); + } + + imprimirRecursivamente(); + }else { + console.log('No hay forma con dicho parametro'); + } + +} + + +// iterationMaster(1); +//iterationMaster(2); +iterationMaster(3); diff --git a/soluciones-javascript/26-piedra-papel-tijera/index.js b/soluciones-javascript/26-piedra-papel-tijera/index.js new file mode 100644 index 000000000..575841b86 --- /dev/null +++ b/soluciones-javascript/26-piedra-papel-tijera/index.js @@ -0,0 +1,66 @@ +/* + * Crea un programa que calcule quien gana más partidas al piedra, + * papel, tijera. + * - El resultado puede ser: "Player 1", "Player 2", "Tie" (empate) + * - La función recibe un listado que contiene pares, representando cada jugada. + * - El par puede contener combinaciones de "R" (piedra), "P" (papel) + * o "S" (tijera). + * - Ejemplo. Entrada: [("R","S"), ("S","R"), ("P","S")]. Resultado: "Player 2". + */ + +/** + * Juego de piedra papel o tijera + * @param {Array>} jugadas - Lista de pares de jugadas, donde cada par es ["R", "P", "S"] + * @return {string} - "Player 1", "Player 2" o "Tie" + */ +const piedraPapelTijera = (jugadas) => { + + const puntaje = { + player1: 0, + player2: 0, + } + + const reglas = { + R: "S", + P: "R", + S: "P" + }; + + jugadas.forEach(([p1, p2]) => { + + if ( reglas[p1] === p2 ){ + puntaje.player1++; + } else if ( reglas[p2] === p1 ) { + puntaje.player2++; + } + + }); + + const { player1, player2 } = puntaje; + + return (player1 > player2) ? "Player 1" : + (player2 > player1) ? "Player 2" : "Tie"; + +} + +// 1 +console.log(piedraPapelTijera([ + ["R", "S"], + ["S", "R"], + ["P", "S"], +])); + +// 2 +console.log(piedraPapelTijera([ + ["S", "P"], + ["S", "R"], + ["P", "R"], +])); + +// Tie +console.log(piedraPapelTijera([ + ["R", "S"], + ["S", "R"], + ["P", "S"], + ["S", "P"], +])); \ No newline at end of file diff --git a/soluciones-javascript/27-cuadrado-y-triangulo-2d/index.js b/soluciones-javascript/27-cuadrado-y-triangulo-2d/index.js new file mode 100644 index 000000000..4e6e40b76 --- /dev/null +++ b/soluciones-javascript/27-cuadrado-y-triangulo-2d/index.js @@ -0,0 +1,74 @@ +/* + * Crea un programa que dibuje un cuadrado o un triángulo con asteriscos "*". + * - Indicaremos el tamaño del lado y si la figura a dibujar es una u otra. + * - EXTRA: ¿Eres capaz de dibujar más figuras? + */ + +/** + * + * @param {*} size + * @param {*} type + */ +const dibujarFigurasGeometricas = (size, type) => { + if (size < 2) throw new Error("El tamaño debe ser 2 o mayor a 2"); + + switch (type) { + case "cuadrado": + dibujarCuadrado(size); + break; + case "triangulo": + dibujarTriangulo(size); + break; + case "rombo": + dibujarRombo(size); + break; + default: + console.log("Tamaño ingresado no existe, ingrese cuadrado - triangulo - rombo"); + break; + } +}; + +const dibujarCuadrado = (size) => { + + const linea = "* ".repeat(size); + + for (let i = 0; i < size; i++) { + + console.log(linea); + + } + +} + +const dibujarTriangulo = (size) => { + + for (let i = 0; i <= size; i++) { + + console.log( " ".repeat(size - i) + "* ".repeat(i)); + + } + +} + +const dibujarRombo = (size) => { + + if ( size % 2 === 0){ + console.log("El tamaño del rombo debe ser impar"); + return; + } + + let half = Math.floor( size / 2 ); + + for (let i = 0; i <= half; i++) { + console.log(" ".repeat(half - i) + "* ".repeat(i + 1)); + } + + for (let i = half - 1; i >= 0; i--) { + console.log(" ".repeat(half - i) + "* ".repeat(i + 1)); + } + +} + +dibujarFigurasGeometricas(11, 'rombo'); +dibujarFigurasGeometricas(6, 'triangulo'); +dibujarFigurasGeometricas(6, 'cuadrado'); \ No newline at end of file diff --git a/soluciones-javascript/28-vectores-ortogonales/index.js b/soluciones-javascript/28-vectores-ortogonales/index.js new file mode 100644 index 000000000..5fed7595c --- /dev/null +++ b/soluciones-javascript/28-vectores-ortogonales/index.js @@ -0,0 +1,29 @@ +/* + * Crea un programa que determine si dos vectores son ortogonales. + * - Los dos array deben tener la misma longitud. + * - Cada vector se podría representar como un array. Ejemplo: [1, -2] + */ + +/** + * + * @param {Array} vectorA + * @param {Array} vectorB + * @returns boolean + */ +const esVectorOrtogonal = (vectorA, vectorB) => { + + if ( vectorA.length !== vectorB.length ) throw new Error("Los Vectores deben tener la misma longitud"); + + let productoEscalar = 0; + + vectorA.forEach( (vector, index) => { + productoEscalar += ( vector * vectorB[index]); + }); + + return productoEscalar === 0; + +} + +// Ejemplo de uso: +console.log(esVectorOrtogonal([1, -2], [2, 1])); // true (son ortogonales) +console.log(esVectorOrtogonal([1, 2, 3], [4, 5, 6])); // false (no son ortogonales) \ No newline at end of file diff --git a/soluciones-javascript/29-maquina-expendedora/index.js b/soluciones-javascript/29-maquina-expendedora/index.js new file mode 100644 index 000000000..4de05e1d1 --- /dev/null +++ b/soluciones-javascript/29-maquina-expendedora/index.js @@ -0,0 +1,98 @@ +/* + * Simula el funcionamiento de una máquina expendedora creando una operación + * que reciba dinero (array de monedas) y un número que indique la selección + * del producto. + * - El programa retornará el nombre del producto y un array con el dinero + * de vuelta (con el menor número de monedas). + * - Si el dinero es insuficiente o el número de producto no existe, + * deberá indicarse con un mensaje y retornar todas las monedas. + * - Si no hay dinero de vuelta, el array se retornará vacío. + * - Para que resulte más simple, trabajaremos en céntimos con monedas + * de 5, 10, 50, 100 y 200. + * - Debemos controlar que las monedas enviadas estén dentro de las soportadas. + */ + +const productos = [ + { codigo: "A1", nombre: "Papitas de Pollo", precio: 100 }, + { codigo: "A3", nombre: "Doritos dinamita", precio: 100 }, + { codigo: "B1", nombre: "agua", precio: 10 }, + { codigo: "B2", nombre: "agua con gas", precio: 100 }, + { codigo: "B3", nombre: "agua con sabor a fresa", precio: 100 }, + { codigo: "C1", nombre: "Gomitas", precio: 100 }, + { codigo: "C2", nombre: "Trululu", precio: 100 }, + { codigo: "C3", nombre: "gomitas acidas", precio: 100 }, + { codigo: "D1", nombre: "Coca Cola", precio: 200 }, + { codigo: "D2", nombre: "Fanta", precio: 200 }, + { codigo: "D3", nombre: "Sprite", precio: 200 }, + { codigo: "E1", nombre: "Margaritas Naturales", precio: 100 }, + { codigo: "E2", nombre: "Margaritas Picantes", precio: 100 }, + { codigo: "E3", nombre: "Doritos", precio: 100 }, +]; + +const monedasSoportadas = [5, 10, 50, 100, 200]; + +const calcularCambio = (cambio) => { + let resultado = []; + + for (let moneda of monedasSoportadas.sort((a, b) => b - a)) { + while (cambio >= moneda) { + + resultado.push(moneda); + + cambio -= moneda; + } + } + + return resultado; +}; + +/** + * Simula el funcionamiento de una máquina expendedora. + * + * @param {Object} param0 - Objeto con la información del pedido. + * @param {number[]} param0.dinero - Array de monedas ingresadas en la máquina. + * @param {string} param0.seleccionProducto - Código del producto seleccionado. + * @returns {string|Object} Mensaje de error o un objeto con el producto y el cambio. + */ +const maquinaExpendedora = ({ dinero, seleccionProducto }) => { + // Validar que todas las monedas ingresadas sean soportadas + if (!dinero.every((m) => monedasSoportadas.includes(m))) { + return "Error: Se han Ingresado monedas no soportadas. Se devuelve el dinero"; + } + + const producto = productos.find((p) => p.codigo === seleccionProducto); + + const dineroTotal = dinero.reduce((acc, moneda) => acc + moneda, 0); + + // Si el producto no existe, devolver dinero + if (!producto) { + return "Error: Producto no encontrado. Se devuelve el dinero."; + } + + // Si el dinero es insuficiente, devolver dinero + if (dineroTotal < producto.precio) { + return "Error: Dinero insuficiente. Se devuelve el dinero."; + } + + const cambio = calcularCambio(dineroTotal - producto.precio); + + return { + producto: producto.nombre, + cambio + }; +}; + +console.log(maquinaExpendedora({ dinero: [100, 50, 50], seleccionProducto: "A1" })); +// { producto: 'Papitas de Pollo', cambio: [100] } + +console.log(maquinaExpendedora({ dinero: [5, 10, 50], seleccionProducto: "B1" })); +// { producto: 'Agua', cambio: [50, 10, 5] } + +console.log(maquinaExpendedora({ dinero: [100, 100], seleccionProducto: "D1" })); +// { producto: 'Coca Cola', cambio: [] } + +console.log(maquinaExpendedora({ dinero: [200], seleccionProducto: "Z1" })); +// "Error: Producto no encontrado. Se devuelve el dinero." + +console.log(maquinaExpendedora({ dinero: [500], seleccionProducto: "A1" })); +// "Error: Se han ingresado monedas no soportadas. Se devuelve el dinero." diff --git a/soluciones-javascript/30-ordena-lista/index.js b/soluciones-javascript/30-ordena-lista/index.js new file mode 100644 index 000000000..cf8134f0e --- /dev/null +++ b/soluciones-javascript/30-ordena-lista/index.js @@ -0,0 +1,61 @@ +/* + * Crea una función que ordene y retorne una matriz de números. + * - La función recibirá un listado (por ejemplo [2, 4, 6, 8, 9]) y un parámetro + * adicional "Asc" o "Desc" para indicar si debe ordenarse de menor a mayor + * o de mayor a menor. + * - No se pueden utilizar funciones propias del lenguaje que lo resuelvan + * automáticamente. + */ + +const ordenarAsc = (lista) => { + let n = lista.length; + for (let i = 0; i < n - 1; i++) { + for (let j = 0; j < n - i - 1; j++) { + if (lista[j] > lista[j + 1]) { + let temp = lista[j]; + lista[j] = lista[j + 1]; + lista[j + 1] = temp; + } + } + } + return lista; +}; + +const ordenarDesc = (lista) => { + let n = lista.length; + for (let i = 0; i < n - 1; i++) { + for (let j = 0; j < n - i - 1; j++) { + if (lista[j] < lista[j + 1]) { + let temp = lista[j]; + lista[j] = lista[j + 1]; + lista[j + 1] = temp; + } + } + } + return lista; +}; +/** + * Función para ordenar un array de números + * @param {Array} lista + * @return ArrayOrdenado + */ +const ordenarLista = ( lista, indicacion ) => { + + if ( !lista.every((num) => typeof num === "number" )){ + return "Error: los elementos del array no son un número" + }; + + switch (indicacion) { + case "Asc": + return ordenarAsc([...lista]); + case "Desc": + return ordenarDesc([...lista]); + default: + return "Error: indicación no válida"; + } + +} + +// Pruebas +console.log(ordenarLista([5, 2, 9, 1, 5, 6], "Asc")); // [1, 2, 5, 5, 6, 9] +console.log(ordenarLista([3, 8, 2, 7, 4], "Desc")); // [8, 7, 4, 3, 2] diff --git a/soluciones-javascript/31-marco-de-palabras/index.js b/soluciones-javascript/31-marco-de-palabras/index.js new file mode 100644 index 000000000..aad6fa653 --- /dev/null +++ b/soluciones-javascript/31-marco-de-palabras/index.js @@ -0,0 +1,38 @@ +/* + * Crea una función que reciba un texto y muestre cada palabra en una línea, + * formando un marco rectangular de asteriscos. + * - ¿Qué te parece el reto? Se vería así: + * ********** + * * ¿Qué * + * * te * + * * parece * + * * el * + * * reto? * + * ********** + */ + +/** + * + * @param {String} sentence + */ +const marcoDePalabras = (sentence) => { + + const sentenceLengthMajor = Math.max(...sentence.split(/[^A-Za-zÁ-Úá-úÜüÑñ]+/).map( element => element.length)); + + const inicioFinMarco = "*".repeat(sentenceLengthMajor + 4); + + + const palabrasSeparadas = inicioFinMarco + "\n" + sentence.trim().split(' ').map( word => { + + const espacios = word.length === sentenceLengthMajor ? 0 : sentenceLengthMajor - word.length; + + return "* " + word + " ".repeat(espacios + 1) + "*"; + }).join('\n').concat("\n" + inicioFinMarco); + + console.log(palabrasSeparadas); + +} + +marcoDePalabras("¿Qué te parece el reto?"); +marcoDePalabras("Esto es otro ejemplo más"); +marcoDePalabras("Esto es una declaración de amor"); \ No newline at end of file diff --git "a/soluciones-javascript/32-a\303\261os-bisiestos/index.js" "b/soluciones-javascript/32-a\303\261os-bisiestos/index.js" new file mode 100644 index 000000000..02084f308 --- /dev/null +++ "b/soluciones-javascript/32-a\303\261os-bisiestos/index.js" @@ -0,0 +1,37 @@ +/* + * Crea una función que imprima los 30 próximos años bisiestos + * siguientes a uno dado. + * - Utiliza el menor número de líneas para resolver el ejercicio. + */ + +const esBisiesto = (year) => { + return ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)); +} + +const calcularBisiesto = (year) => { + + if (!esBisiesto(year)) { + return "Error: debes ingresar un año bisiesto" + } + + const proximosBisiestos = []; + + for (let i = 1; i <= 30; i++) { + + year += 4; + + if (esBisiesto(year)) { + proximosBisiestos.push(year); + } else { + i--; + } + + } + + return proximosBisiestos; + +} + +console.log(calcularBisiesto(2024)); +console.log(calcularBisiesto(2000)); +console.log(calcularBisiesto(1900)); \ No newline at end of file diff --git a/soluciones-javascript/33-el-segundo/index.js b/soluciones-javascript/33-el-segundo/index.js new file mode 100644 index 000000000..6c8aa917f --- /dev/null +++ b/soluciones-javascript/33-el-segundo/index.js @@ -0,0 +1,23 @@ +/* + * Dado un listado de números, encuentra el SEGUNDO más grande + */ + +/** + * + * @param {Array} lista + */ +const elSegundoMasGrande = (lista) => { + + const listaFormateada = lista.filter( (value, index, array) => array.indexOf(value) === index); + + listaFormateada.sort((a, b) => b - a ).shift(); + + return listaFormateada.shift(); + +} + +console.log(elSegundoMasGrande([1,98,2,4,56,8,9,55])); +console.log(elSegundoMasGrande([100, 100, 50])); // Retorna 50 (Correcto) +console.log(elSegundoMasGrande([100, 100])); // Retorna 100 (Incorrecto, debería ser undefined o indicar que no hay segundo más grande) +console.log(elSegundoMasGrande([42])); // Retorna undefined (No hay segundo más grande) +console.log(elSegundoMasGrande([])); // Retorna undefined (Correcto, pero podría manejarse mejor) diff --git a/soluciones-javascript/34-ciclo-sexagenario-chino/index.js b/soluciones-javascript/34-ciclo-sexagenario-chino/index.js new file mode 100644 index 000000000..c0134d11a --- /dev/null +++ b/soluciones-javascript/34-ciclo-sexagenario-chino/index.js @@ -0,0 +1,37 @@ +/* + * Crea un función, que dado un año, indique el elemento + * y animal correspondiente en el ciclo sexagenario del zodíaco chino. + * - Info: https://www.travelchinaguide.com/intro/astrology/60year-cycle.htm + * - El ciclo sexagenario se corresponde con la combinación de los elementos + * madera, fuego, tierra, metal, agua y los animales rata, buey, tigre, + * conejo, dragón, serpiente, caballo, oveja, mono, gallo, perro, cerdo + * (en este orden). + * - Cada elemento se repite dos años seguidos. + * - El último ciclo sexagenario comenzó en 1984 (Madera Rata). + */ + +const cicloSexagenarioChino = (year) => { + + const elements = [ "madera", "fuego", "tierra", "metal", "agua" ]; + const animals = [ "rata", "buey", "tigre", "conejo", "dragón", "serpiente", "caballo", "oveja", "mono", "gallo", "perro", "cerdo"]; + + if ( year < 604) { + return "El ciclo sexagenario comenzó en el año 604"; + } + + const sexagenaryYear = Math.floor((year - 4) % 60); + const elementsYear = elements[Math.floor((sexagenaryYear % 10) / 2)]; + const animalsYear = animals[Math.floor(sexagenaryYear % 12)]; + + + return `El año ${year}: ${elementsYear} ${animalsYear}`; + +} + +console.log(cicloSexagenarioChino(1924)); +console.log(cicloSexagenarioChino(1946)); +console.log(cicloSexagenarioChino(1984)); +console.log(cicloSexagenarioChino(604)); +console.log(cicloSexagenarioChino(603)); +console.log(cicloSexagenarioChino(1987)); +console.log(cicloSexagenarioChino(2022)); \ No newline at end of file diff --git a/soluciones-javascript/35-los-numeros-perdidos/index.js b/soluciones-javascript/35-los-numeros-perdidos/index.js new file mode 100644 index 000000000..3d5989921 --- /dev/null +++ b/soluciones-javascript/35-los-numeros-perdidos/index.js @@ -0,0 +1,50 @@ +/* + * Dado un array de enteros ordenado y sin repetidos, + * crea una función que calcule y retorne todos los que faltan entre + * el mayor y el menor. + * - Lanza un error si el array de entrada no es correcto. + */ + +/** + * + * @param {Array} array + */ +const numerosPerdidos = (array) => { + + if (!Array.isArray(array)) throw new Error("El parámetro debe ser un array."); + if (array.length === 0) throw new Error("El array no debe estar vacío."); + if (!array.every(num => Number.isInteger(num))) throw new Error("Todos los elementos deben ser números enteros."); + + // Verificar si el array está ordenado de menor a mayor + for (let i = 0; i < array.length - 1; i++) { + if (array[i] >= array[i + 1]) { + return "El array debe estar ordenado de menor a mayor y sin repetidos."; + } + } + + const numerosFaltantes = []; + + for (let i = 0; i < array.length; i++) { + + const numeroSuperior = array[i + 1] || 0; + + if ( (numeroSuperior - array[i]) > 1){ + const diferencial = (numeroSuperior - array[i]); + + for (let j = 1; j < diferencial; j++) { + numerosFaltantes.push(numeroSuperior - (diferencial - j)); + } + + } + + } + + return numerosFaltantes; + +} + +// Pruebas +console.log(numerosPerdidos([1, 3, 4, 7])); // [2, 5, 6] +console.log(numerosPerdidos([1, 4, 10])); // [2, 3, 5, 6, 7, 8, 9] +console.log(numerosPerdidos([5, 6, 8, 17, 20])); // [7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19] +console.log(numerosPerdidos([1, 2, 3, 4, 5])); // [] \ No newline at end of file diff --git a/soluciones-javascript/36-batalla-pokemon/index.js b/soluciones-javascript/36-batalla-pokemon/index.js new file mode 100644 index 000000000..2a0915dea --- /dev/null +++ b/soluciones-javascript/36-batalla-pokemon/index.js @@ -0,0 +1,38 @@ +/* + * Crea un programa que calcule el daño de un ataque durante + * una batalla Pokémon. + * - La fórmula será la siguiente: daño = 50 * (ataque / defensa) * efectividad + * - Efectividad: x2 (súper efectivo), x1 (neutral), x0.5 (no es muy efectivo) + * - Sólo hay 4 tipos de Pokémon: Agua, Fuego, Planta y Eléctrico + * (buscar su efectividad) + * - El programa recibe los siguientes parámetros: + * - Tipo del Pokémon atacante. + * - Tipo del Pokémon defensor. + * - Ataque: Entre 1 y 100. + * - Defensa: Entre 1 y 100. + */ + +const tiposDeEfectividad = { + agua: { fuego: 2, planta: 0.5, electrico: 0.5, agua: 1 }, + fuego: { planta: 2, agua: 0.5, electrico: 1, fuego: 1 }, + planta: { agua: 2, fuego: 0.5, electrico: 0.5, planta: 1 }, + electrico: { agua: 2, planta: 0.5, fuego: 1, electrico: 1 }, +} + +const calcularDamageInBattle = (tipoAtacante, tipoDefensor, ataque, defensa) => { + + if (!tiposDeEfectividad[tipoAtacante] || !tiposDeEfectividad[tipoAtacante][tipoDefensor]) { + throw new Error("Tipo de Pokémon inválido"); + } + + const tipoEfectividad = tiposDeEfectividad[tipoAtacante][tipoDefensor]; + + return 50 * ( ataque / defensa ) * tipoEfectividad; + + +} + +console.log(calcularDamageInBattle("agua", "electrico", 40, 70)); +console.log(calcularDamageInBattle("agua", "fuego", 80, 50)); // Daño esperado alto (súper efectivo) +console.log(calcularDamageInBattle("fuego", "agua", 60, 70)); // Daño esperado bajo (no muy efectivo) +console.log(calcularDamageInBattle("planta", "planta", 90, 90)); // Daño esperado neutro (x1) \ No newline at end of file diff --git a/soluciones-javascript/37-los-anillos-del-poder/index.js b/soluciones-javascript/37-los-anillos-del-poder/index.js new file mode 100644 index 000000000..9cbfe9b6e --- /dev/null +++ b/soluciones-javascript/37-los-anillos-del-poder/index.js @@ -0,0 +1,83 @@ +/* + * ¡La Tierra Media está en guerra! En ella lucharán razas leales + * a Sauron contra otras bondadosas que no quieren que el mal reine + * sobre sus tierras. + * Cada raza tiene asociado un "valor" entre 1 y 5: + * - Razas bondadosas: Pelosos (1), Sureños buenos (2), Enanos (3), + * Númenóreanos (4), Elfos (5) + * - Razas malvadas: Sureños malos (2), Orcos (2), Goblins (2), + * Huargos (3), Trolls (5) + * Crea un programa que calcule el resultado de la batalla entre + * los 2 tipos de ejércitos: + * - El resultado puede ser que gane el bien, el mal, o exista un empate. + * Dependiendo de la suma del valor del ejército y el número de integrantes. + * - Cada ejército puede estar compuesto por un número de integrantes variable + * de cada raza. + * - Tienes total libertad para modelar los datos del ejercicio. + * Ej: 1 Peloso pierde contra 1 Orco + * 2 Pelosos empatan contra 1 Orco + * 3 Pelosos ganan a 1 Orco + */ + +const razasBondadosas = { + pelosos: 1, + sureniosBuenos: 2, + enanos: 3, + numenoreanos: 4, + elfos: 5 +} + +const razasMalvadas = { + sureniosMalosMalos: 2, + orcos: 2, + goblins: 2, + huargos: 3, + trolls: 5 +} + +const calculoRazaVencedora = ( ejercitoBondadoso, ejercitoMalvado ) => { + let puntosBondadosos = 0; + let puntosMalvados = 0; + + ejercitoBondadoso.forEach(raza => { + const [ nombre, cantidad ] = Object.entries(raza)[0]; + + if( razasBondadosas[nombre]) { + puntosBondadosos += razasBondadosas[nombre] * cantidad; + } + }); + + ejercitoMalvado.forEach(raza => { + const [ nombre, cantidad] = Object.entries(raza)[0]; + + if( razasMalvadas[nombre]) { + puntosMalvados += razasMalvadas[nombre] * cantidad; + }; + }); + + + return puntosBondadosos > puntosMalvados + ? 'El bien triunfa sobre el mal' + : puntosMalvados > puntosBondadosos + ? 'El mal triunfa sobre el bien' + : 'La batalla fue un empate'; + +} + +const ejercitoBondadoso = [ + {pelosos: 2,}, + {sureniosBuenos: 3,}, + {enanos: 4, }, + {numenoreanos: 2, }, + {elfos: 5,}, +]; +const ejercitoMalvado = [ + {sureniosMalosMalos: 2,} , + {orcos: 2, }, + {goblins: 2,}, + {huargos: 3, }, + {trolls: 5}, +]; + + +console.log(calculoRazaVencedora(ejercitoBondadoso, ejercitoMalvado)); \ No newline at end of file diff --git a/soluciones-javascript/38-lanzamientos-legend-of-zelda/index.js b/soluciones-javascript/38-lanzamientos-legend-of-zelda/index.js new file mode 100644 index 000000000..3c3d63484 --- /dev/null +++ b/soluciones-javascript/38-lanzamientos-legend-of-zelda/index.js @@ -0,0 +1,54 @@ +/* + * ¡Han anunciado un nuevo "The Legend of Zelda"! + * Se llamará "Tears of the Kingdom" y se lanzará el 12 de mayo de 2023. + * Pero, ¿recuerdas cuánto tiempo ha pasado entre los distintos + * "The Legend of Zelda" de la historia? + * Crea un programa que calcule cuántos años y días hay entre 2 juegos de Zelda + * que tú selecciones. + * - Debes buscar cada uno de los títulos y su día de lanzamiento + * (si no encuentras el día exacto puedes usar el mes, o incluso inventártelo) + */ + +/** + * Compara dos juegos en función de su nombre y año de lanzamiento. + * + * @param {{ name: string, releaseYear: string }} juego1 - Primer juego a comparar. + * @param {{ name: string, releaseYear: string }} juego2 - Segundo juego a comparar. + */ +const lanzamientosLegendOfZelda = (juego1, juego2) => { + const { name, releaseYear } = juego1; + const { name: name2, releaseYear: releaseYear2 } = juego2; + + const fechaJuego1 = new Date(releaseYear); + const fechaJuego2 = new Date(releaseYear2); + + let anios = fechaJuego2.getFullYear() - fechaJuego1.getFullYear() ; + let meses = fechaJuego2.getMonth() - fechaJuego1.getMonth(); + let dias = fechaJuego2.getDate() - fechaJuego1.getDate(); + + if ( dias < 0){ + meses--; + const mesAnterior = new Date(fechaJuego2.getFullYear(), fechaJuego2.getMonth(), 0); + dias += mesAnterior.getDate(); + } + + if (meses < 0) { + anios--; + meses += 12; + } + + console.log( { anios, meses, dias } ); + + +}; + +lanzamientosLegendOfZelda( + { + name: "The Legend of Zelda: Ocarina of Time", + releaseYear: "12/11/1998", + }, + { + name: "Zelda: Majoras Mask", + releaseYear: "11/17/2000", + } +); diff --git a/soluciones-javascript/39-binario-a-decimal/index.js b/soluciones-javascript/39-binario-a-decimal/index.js new file mode 100644 index 000000000..6c92f8b5c --- /dev/null +++ b/soluciones-javascript/39-binario-a-decimal/index.js @@ -0,0 +1,31 @@ +/* + * Crea un programa se encargue de transformar un número binario + * a decimal sin utilizar funciones propias del lenguaje que + * lo hagan directamente. + */ + +/** + * + * @param {Number} numeroBinario + */ +const binaryToDecimal = (numeroBinario) => { + + const stringNumeroBinario = numeroBinario.toString(); + let resultado = 0; + let exponente = 0; + + for (let i = 1; i <= stringNumeroBinario.length; i++) { + + const number = Number(stringNumeroBinario[ stringNumeroBinario.length - i]); + + resultado += (number * Math.pow(2, exponente)); + exponente++; + } + + return resultado; + +} + +console.log(binaryToDecimal(1011)); +console.log(binaryToDecimal(1010)); +console.log(binaryToDecimal(11111111)); \ No newline at end of file diff --git a/soluciones-javascript/40-top-algoritmos/index.js b/soluciones-javascript/40-top-algoritmos/index.js new file mode 100644 index 000000000..625d4c20c --- /dev/null +++ b/soluciones-javascript/40-top-algoritmos/index.js @@ -0,0 +1,41 @@ +/* + * Implementa uno de los algoritmos de ordenación más famosos: + * el "Quick Sort", creado por C.A.R. Hoare. + * - Entender el funcionamiento de los algoritmos más utilizados de la historia + * Nos ayuda a mejorar nuestro conocimiento sobre ingeniería de software. + * Dedícale tiempo a entenderlo, no únicamente a copiar su implementación. + * - Esta es una nueva serie de retos llamada "TOP ALGORITMOS", + * donde trabajaremos y entenderemos los más famosos de la historia. + */ + +/** + * + * @param {Array} array + */ +const quickSort = (array) => { + + if (array.length <= 1 ) { + return array; + } + + const pivot = array[array.length - 1]; + const left = []; + const right = []; + + for (let i = 0; i < array.length - 1; i++) { + + if (array[i] < pivot ) { + left.push(array[i]); + } else{ + right.push(array[i]); + } + + } + + console.log({left, right}) + + return [ ...quickSort(left), pivot, ...quickSort(right) ]; + +} + +console.log(quickSort([ 8, 9, 3, 7, 1, 2, 6, 4])); \ No newline at end of file diff --git a/soluciones-javascript/41-triangulo-de-pascal/index.js b/soluciones-javascript/41-triangulo-de-pascal/index.js new file mode 100644 index 000000000..c51e3a012 --- /dev/null +++ b/soluciones-javascript/41-triangulo-de-pascal/index.js @@ -0,0 +1,41 @@ +/* + * Crea una función que sea capaz de dibujar el "Triángulo de Pascal" + * indicándole únicamente el tamaño del lado. + * + * - Aquí puedes ver rápidamente cómo se calcula el triángulo: + * https://commons.wikimedia.org/wiki/File:PascalTriangleAnimated2.gif + */ + +const generarTrianguloPascal = (n) => { + let triangulo = []; + + for (let i = 0; i < n; i++) { + triangulo[i] = []; + for (let j = 0; j <= i; j++) { + if (j === 0 || j === i) { + triangulo[i][j] = 1; + } else { + triangulo[i][j] = triangulo[i - 1][j - 1] + triangulo[i - 1][j]; + } + } + } + + return triangulo; +} + +const imprimirTrianguloPascal = (triangulo) => { + let n = triangulo.length; + let resultado = ""; + + for (let i = 0; i < n; i++) { + let espacio = " ".repeat(n - i); + let fila = triangulo[i].join(" "); + resultado += espacio + fila + "\n"; + } + + console.log(resultado); +} + +let n = 5; // Tamaño del triángulo +let triangulo = generarTrianguloPascal(n); +imprimirTrianguloPascal(triangulo); diff --git a/soluciones-javascript/42-la-ley-de-ohm/index.js b/soluciones-javascript/42-la-ley-de-ohm/index.js new file mode 100644 index 000000000..88c0cd6c3 --- /dev/null +++ b/soluciones-javascript/42-la-ley-de-ohm/index.js @@ -0,0 +1,37 @@ +/* + * Crea una función que calcule el valor del parámetro perdido + * correspondiente a la ley de Ohm. + * - Enviaremos a la función 2 de los 3 parámetros (V, R, I), y retornará + * el valor del tercero (redondeado a 2 decimales). + * - Si los parámetros son incorrectos o insuficientes, la función retornará + * la cadena de texto "Invalid values". + */ + +/** + * + * @param {{ v: Number, r: Number, i: Number }} param0 + */ +const leyDeOhm = ({ v, r, i }) => { + + const valores = [ v, r, i ]; + const faltantes = valores.filter( value => value === undefined ).length; + + if ( faltantes !== 1 || valores.some( value => value !== undefined && (typeof value !== "number") || value < 0)) + return "Invalid Values"; + + return v === undefined + ? (i * r).toFixed(2) + : r === undefined + ? (v / i).toFixed(2) + : i === undefined + ? (v / r).toFixed(2) + : 'Invalid values'; +} + +console.log(leyDeOhm({ v: 0, r: 2, i: 3 })); // "Invalid values" +console.log(leyDeOhm({ v: undefined, r: 4, i: 5 })); // 20.00 +console.log(leyDeOhm({ v: 12, r: undefined, i: 3 })); // 4.00 +console.log(leyDeOhm({ v: 12, r: 4, i: undefined })); // 3.00 +console.log(leyDeOhm({ v: 12, r: 4, i: 3 })); // "Invalid values" +console.log(leyDeOhm({ v: -12, r: 4, i: undefined })); // "Invalid values" +console.log(leyDeOhm({ v: 12, r: "4", i: undefined })); // "Invalid values" \ No newline at end of file diff --git a/soluciones-javascript/43-conversor-temperatura/index.js b/soluciones-javascript/43-conversor-temperatura/index.js new file mode 100644 index 000000000..6b0a4e670 --- /dev/null +++ b/soluciones-javascript/43-conversor-temperatura/index.js @@ -0,0 +1,44 @@ +/* + * Crea una función que transforme grados Celsius en Fahrenheit + * y viceversa. + * + * - Para que un dato de entrada sea correcto debe poseer un símbolo "°" + * y su unidad ("C" o "F"). + * - En caso contrario retornará un error. + */ + +/** + * + * @param {String} grados + */ +const conversorTemperatura = ( grados ) => { + + const reglaRegex = /^-?\d+(\.\d+)?\s*°\s*[cCfF]$/; + + if (!reglaRegex.test(grados)) { + return "Error en el formato" + } + + const numGrado = grados.split('').map((g) => { + return !isNaN(Number(g)) ? g : null + }).join(''); + + const condicion = grados.split('').filter((letra) => letra === "C" || letra === "F" ).join(''); + + if (condicion === "C") { + + return `${numGrado * (9 / 5) + 32} °F`; + + } else if ( condicion === "F" ){ + + return `${(numGrado - 32 ) * (5 / 9)} °C`; + + } else { + return "Error en la letra" + } +} + +// Pruebas +console.log(conversorTemperatura("25 °C")); // 77.00 °F +console.log(conversorTemperatura("77 °F")); // 25.00 °C +console.log(conversorTemperatura("abc °C")); // Error en el formato \ No newline at end of file diff --git a/soluciones-javascript/44-truco-o-trato/index.js b/soluciones-javascript/44-truco-o-trato/index.js new file mode 100644 index 000000000..902ac8e88 --- /dev/null +++ b/soluciones-javascript/44-truco-o-trato/index.js @@ -0,0 +1,99 @@ +/* + * Este es un reto especial por Halloween. + * Deberemos crear un programa al que le indiquemos si queremos realizar "Truco + * o Trato" y un listado (array) de personas con las siguientes propiedades: + * - Nombre de la niña o niño + * - Edad + * - Altura en centímetros + * + * Si las personas han pedido truco, el programa retornará sustos (aleatorios) + * siguiendo estos criterios: + * - Un susto por cada 2 letras del nombre por persona + * - Dos sustos por cada edad que sea un número par + * - Tres sustos por cada 100 cm de altura entre todas las personas + * - Sustos: 🎃 👻 💀 🕷 🕸 🦇 + * + * Si las personas han pedido trato, el programa retornará dulces (aleatorios) + * siguiendo estos criterios: + * - Un dulce por cada letra de nombre + * - Un dulce por cada 3 años cumplidos hasta un máximo de 10 años por persona + * - Dos dulces por cada 50 cm de altura hasta un máximo de 150 cm por persona + * - Dulces: 🍰 🍬 🍡 🍭 🍪 🍫 🧁 🍩 + * - En caso contrario retornará un error. + */ + +const trucoOTrato = (decision, arrayDePersonas) => { + const sustos = ["🎃", "👻", "💀", "🕷", "🕸", "🦇"]; + const dulces = ["🍰", "🍬", "🍡", "🍭", "🍪", "🍫", "🧁", "🍩"]; + const resultado = []; + + if (decision === "Truco") { + let sumaEdades = 0; + + arrayDePersonas.forEach((element) => { + const [nombre, edad, centimetro] = element; + + // Un susto por cada 2 letras del nombre por persona + if (nombre.length % 2 === 0) { + for (let i = 0; i < nombre.length / 2; i++) { + resultado.push(sustos[Math.floor(Math.random() * 6)]); + } + } else { + for (let i = 0; i < (nombre.length - 1) / 2; i++) { + resultado.push(sustos[Math.floor(Math.random() * 6)]); + } + } + + // Dos sustos por cada edad que sea un número par + if (edad % 2 === 0) { + for (let i = 0; i < 2; i++) { + resultado.push(sustos[Math.floor(Math.random() * 6)]); + } + } + + sumaEdades += centimetro; + }); + + // Tres sustos por cada 100 cm de altura entre todas las personas + for (let i = 100; i <= sumaEdades; i += 100) { + for (let j = 0; j < 3; j++) { + resultado.push(sustos[Math.floor(Math.random() * 6)]); + } + } + } else if (decision === "Trato") { + arrayDePersonas.forEach((element) => { + const [nombre, edad, centimetro] = element; + + // Un dulce por cada letra de nombre + for (let i = 0; i < nombre.length; i++) { + resultado.push(dulces[Math.floor(Math.random() * 8)]); + } + + // Un dulce por cada 3 años cumplidos hasta un máximo de 10 años por persona + for (let j = 0; j < edad; j += 3) { + resultado.push(dulces[Math.floor(Math.random() * 8)]); + } + + // Dos dulces por cada 50 cm de altura hasta un máximo de 150 cm por persona + for (let y = 0; y < 150; y += 50) { + if ( y > centimetro ) return resultado; + resultado.push(dulces[Math.floor(Math.random() * 8)]); + } + + }); + } else { + return "Error"; + } + + return resultado.join(" "); +}; + +const personas = [ + ["Juan", 10, 100], + ["Pablo", 8, 120], + ["Carla", 7, 80], + ["Lina", 9, 110], +]; + +console.log("Truco" + trucoOTrato("Truco", personas) + "\n"); +console.log("Trato" + trucoOTrato("Trato", personas) + "\n");