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