├── Ejercicios ├── 01-FindNeedle │ ├── FindNeedle.js │ └── README.md ├── 02-SumArray │ ├── README.md │ └── SumArray.js ├── 03-MaxValue │ ├── MaxValue.js │ └── README.md ├── 04-MultidimensionalSumArray │ ├── MultidimensionalSumArray.js │ └── README.md ├── 05-MinStack │ ├── MinStack.js │ └── README.md ├── 06-HasBalanceBrackets │ ├── HasBalanceBrackets.js │ └── README.md ├── 07-SolveGraph │ ├── README.md │ └── SolveGraph.js ├── 08-FindWordStartingWith │ ├── FindWordStartingWith.js │ └── README.md ├── 09-BinaryToDecimal │ ├── BinaryToDecimal.js │ └── README.md ├── 10-DecimalToBynary │ ├── DecimalToBynary.js │ └── README.md ├── 11-ClockMinuteAdder │ ├── ClockMinuteAdder.js │ └── README.md ├── 12-Intersection │ ├── Intersection.js │ └── README.md ├── 13-SubSetSum │ ├── README.md │ └── SubSetSum.js ├── 14-LongestIncreasingSubSequence │ ├── LongestIncreasingSubSequence.js │ └── README.md ├── 15-SpyOn │ ├── README.md │ └── SpyOn.js ├── 16-Curry │ ├── Curry.js │ └── README.md └── Tests │ ├── coverage │ ├── clover.xml │ ├── coverage-final.json │ ├── lcov-report │ │ ├── base.css │ │ ├── block-navigation.js │ │ ├── bracketValidator.js.html │ │ ├── favicon.png │ │ ├── index.html │ │ ├── indexArray.js.html │ │ ├── mayorGanancia.js.html │ │ ├── minStack.js.html │ │ ├── multidimensionalArray.js.html │ │ ├── prettify.css │ │ ├── prettify.js │ │ ├── sort-arrow-sprite.png │ │ └── sorter.js │ └── lcov.info │ ├── jest.config.js │ ├── package-lock.json │ ├── package.json │ ├── problems │ ├── binarioaDecimal.js │ ├── bracketValidator.js │ ├── decimalABinario.js │ ├── indexArray.js │ ├── maxValue │ ├── mayorGanancia.js │ ├── minStack.js │ ├── multidimensionalArray.js │ ├── nCapicua.js │ └── stackOcurrencia.js │ └── test │ ├── 01-FindNeedle.spec.js │ ├── 02-SumArray.spec.js │ ├── 03-MaxValue.spec.js │ ├── 04-multidimensionalArray.spec.js │ ├── 05-minStack.spec.js │ ├── 06-HasBalancedBrackets.spec.js │ ├── 07-SolveGraph.spec.js │ ├── 08-FindWordStartingWith.spec.js │ ├── 09-binaryToDecimal.spec.js │ ├── 10-DecimalToBinary.spec.js │ ├── 11-ClockMinuteAdder.spec.js │ ├── 12-InterSection.spec.js │ ├── 13-SubSetSum.spec.js │ ├── 14-SpyOn.spec.js │ └── 15-Curry.spec.js ├── Plantillas.md ├── README.md └── images ├── binary-decimal.png ├── emoticon_duda.png ├── emoticon_gafas.png ├── fantino.png ├── grafico_complejidad.png ├── graph 1.png ├── graph 2.png ├── graph.png ├── perro_programador.png ├── sumArray.png └── sumArray_true_false.png /Ejercicios/01-FindNeedle/FindNeedle.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | //needle: redux 5 | // 6 | //haystack: react-redux 7 | // 8 | //output: 5 9 | // 10 | //needle: puntual 11 | // 12 | //haystack: pinky 13 | // 14 | //output: -1 15 | // 16 | 17 | function FindNeedle(needle, haystack) { 18 | //Escribir la funcion 19 | } 20 | -------------------------------------------------------------------------------- /Ejercicios/01-FindNeedle/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Find Needle 4 | ## Introducción 5 | Encontrar el indice de la primera aparición de un string (needle) dentro de otro (haystack). 6 | 7 | Es decir, el objetivo del ejercicio es determinar si el primer string, needle, esta dentro del segundo, haystack, y en dicho caso, devolver el indice en el que esto ocurre. 8 | 9 | #### Ejemplos 10 | ###### Lo encuentra 11 | **needle**: redux 12 | **haystack**: react-redux 13 | **output**: 6 14 | 15 | ###### No lo encuentra 16 | **needle**: puntual 17 | **haystack**: pinky 18 | **output**: -1 19 | 20 | En este caso, como el needle no se encuentra en el haystack el valor de salida es -1. 21 | 22 | #### IMPORTANTE 23 | Para la resolución de este ejercicio no se puede utilizar la función preexistente: indexOf( ) 24 | 25 | 26 | ## Solución 27 | ### En palabras 28 | 1. Visitar cada caracter del haystack 29 | 2. Visitar cada caracter del needle, si el primer caracter coincide: 30 | 1. Comparar el segundo caracter del needle con el siguiente del haystack 31 | 2. Continuar hasta llegar al final del needle o hasta que una comparación no sea igual 32 | 1. Si llegamos al final del needle es que encontramos el indice 33 | 3. Si el primer caracter del needle no coincide, avanzo al próximo caracter 34 | 4. Llegamos al final del haystack y no encontramos ninguna coincidencia 35 | 36 | ### Primer Alternativa 37 | Ahora si, busquemos la forma de traducir lo que ya dijimos en palabras a código.
38 | Ademas, debemos evaluar la complejidad en tiempo y espacio. 39 | ```javascript 40 | const findNeedle = (haystack, needle) => { 41 | // iteramos sobre el haystack 42 | for (let haystackIndex = 0; haystackIndex < haystack.length; haystackIndex += 1) { 43 | // comenzamos a iterar sobre el needle 44 | for (let needleIndex = 0; needleIndex < needle.length; needleIndex += 1 ) { 45 | // comparamos la letra del needle en la que estamos con la letra del haystack 46 | // cuando no hay match cortamos de comparar el needle 47 | if (haystack[haystackIndex + needleIndex] !== needle[needleIndex]) break; 48 | // si terminamos de recorrer la needle devolvemos el haystackIndex 49 | if (needleIndex + 1 === needle.length) return haystackIndex; 50 | } 51 | } 52 | // una vez que termina el loop y no encontramos match devolvemos -1 53 | return -1; 54 | } 55 | ``` 56 | Considerando **haystack.length = n** y **needle.length = m** 57 | 58 | Complejidad temporal | Complejidad espacial 59 | --|-- 60 | O(n*m)|O(1) 61 | 62 | ### Segunda Alternativa 63 | Otra forma de resolver el ejercicio, es utilizando la función slice. 64 | 65 | ```javascript 66 | function findNeedle2(haystack, needle){ 67 | // iterar sobre el haystack 68 | for (let i = 0; i < haystack.length; i += 1) { 69 | // si la substring matchea el neddle podemos devoler el valor de i 70 | if (haystack.slice(i, i + needle.length) === needle) { 71 | return i; 72 | } 73 | } 74 | return -1; 75 | } 76 | ``` 77 | Considerando **haystack.length = n** y **needle.length = m** 78 | 79 | Complejidad temporal | Complejidad espacial 80 | --|-- 81 | O(n*m)|O(1) 82 | 83 | 84 | ## Código 85 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/Jc2b/0). 86 | -------------------------------------------------------------------------------- /Ejercicios/02-SumArray/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Sum Array 4 | ## Introducción 5 | En este caso se nos presentan dos elementos: una arreglo **ordenado** de números enteros y un número entero. 6 | El objetivo del ejercicio es encontrar si la combinación de dos números cualesquiera del arreglo, suman el número dado. 7 | 8 | #### Ejemplos 9 | ###### Existen dos valores 10 | **arreglo**: [2,4,5,9] 11 | **número**: 9 12 | **return**: true 13 | 14 | ###### No existen dos valores 15 | **arreglo**: [2,4,5,9] 16 | **número**: 12 17 | **return**: false 18 | 19 | ## Solución 20 | Como todo ejercicio, existen múltiples soluciones para un mismo problema. 21 | En este caso, analizáremos dos alternativas diferentes, luego determináremos cual es mejor. 22 | 23 | ### En palabras 24 | 1. Recorrer el arreglo con dos indices 25 | 2. Chequear si la suma de ambas posiciones da el valor pasado por parámetro 26 | 1. Si da, hemos terminado. Encontramos los valores buscados 27 | 2. Si no, seguimos avanzando 28 | 3. Si uno de los indices llego al final, hemos finalizado el recorrido y no existen dos valores en el arreglo que logren la suma esperada 29 | 30 | ### Primer alternativa: Solución naive 31 | ```javascript 32 | functionsumArray (arr, n) { 33 | // Itero sobre el arreglo 34 | for (let i = 0; i < arr.length - 1; i += 1) { 35 | // Itero sobre los números siguientes 36 | for (let j = i + 1; j < arr.length; j += 1) { 37 | // Veo si son iguales a la suma y devuelvo true 38 | if (arr[i] + arr[j] === n) return true; 39 | } 40 | } 41 | // Si termine de recorrer el arreglo devuelvo alse 42 | return false; 43 | } 44 | ``` 45 | 46 | Complejidad Temporal | Complejidad Espacial 47 | --|-- 48 | O(n^2)|O(1) 49 | 50 | ### Segunda alternativa: Mejor solución 51 | ```javascript 52 | function sumArray2 (arr, n) { 53 | // Creo un puntero para el principio y el final 54 | let start = 0; 55 | let end = arr.length - 1; 56 | // Mientras el puntero del principio sea menor al del final 57 | while (start < end) { 58 | // guardo el resultado de la suma 59 | const sum = arr[start] + arr[end]; 60 | // Si son iguales devuelvo true 61 | if ( sum === n) return true; 62 | // Si es menor aumento el puntero de start 63 | else if (sum < n) start += 1; 64 | // Si es mayor decremento el puntero de end 65 | else end -= 1; 66 | } 67 | // Si salimos del for loop significa que no hay coincidencia 68 | return false; 69 | } 70 | ``` 71 | 72 | Complejidad Temporal | Complejidad Espacial 73 | --|-- 74 | O(n)|O(1) 75 | 76 | ## Código 77 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/Jh9N/0). 78 | -------------------------------------------------------------------------------- /Ejercicios/02-SumArray/SumArray.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | // arreglo: [2,4,5,9] 5 | // 6 | // numero: 9 7 | // 8 | // return: true 9 | // 10 | // arreglo: [2,4,5,9] 11 | // 12 | // numero: 12 13 | // 14 | // return: false 15 | // 16 | function SumArray(array) { 17 | //Escribir la funcion 18 | } 19 | -------------------------------------------------------------------------------- /Ejercicios/03-MaxValue/MaxValue.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | // acciones: [4, 3,2,5,11] 5 | // 6 | // mayor ganancia: 9 7 | // 8 | 9 | function MaxValue(array) { 10 | //Escribir la funcion 11 | } 12 | -------------------------------------------------------------------------------- /Ejercicios/03-MaxValue/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Max Value 4 | ## Introducción 5 | Se nos presenta un arreglo de enteros, estos representan el valor de una acción con el pasar del tiempo. ¿El objetivo del ejercicio? Encontrar cuál es la máxima ganancia posible de comprar a un horario y vender a otro después. 6 | 7 | 8 | #### Ejemplo 9 | **acciones**: [4, 3, 2, 5, 11] 10 | **mayor ganancia**: 9 11 | 12 | Esta ganancia la obtenemos comprando la acción cuando su valor es de 2 y vendiéndola cuando a 11. 13 | 14 | ## Solución 15 | 16 | ### Primer alternativa: Solución Fuerza Bruta 17 | ```javascript 18 | const maxValue = (stocks) => { 19 | // guardamos la primer diferencia 20 | let max = stocks[1] - stocks[0]; 21 | // iteramos sobre cada posibilidad de compra 22 | for (let i = 0; i < stocks.length - 1; i += 1) { 23 | // e iteramos sobre cada posibilidad de venta 24 | for (let j = i + 1; j < stocks.length; j += 1){ 25 | // sacamos ganancia potencial 26 | const potential = stocks[j] - stocks[i]; 27 | // y deducimos si nos quedamos con el potencial o con el viejo máximo 28 | max = potential > max ? potential : max; 29 | } 30 | } 31 | // devolvemos el máximo 32 | return max; 33 | }; 34 | ``` 35 | 36 | Complejidad Temporal | Complejidad Espacial 37 | --|-- 38 | O(n^2)|O(1) 39 | 40 | 41 | ### Segunda alternativa: Solución Optima 42 | ```javascript 43 | const maxValue2 = (stocks) => { 44 | // guardamos la primer diferencia 45 | let max = stocks[1] - stocks[0]; 46 | // guardamos el precio mínimo hasta el momento 47 | let minPrice = stocks[0]; 48 | // iteramos sobre las stocks 49 | for (let i = 1; i < stocks.length; i += 1) { 50 | // sacamos la ganacia potencial 51 | const potencial = stocks[i] - minPrice; 52 | // Nos quedamos con el mayor valor 53 | max = Math.max(max, potencial); 54 | // nos quedamos con el precio mínimo 55 | minPrice = Math.min(minPrice, stocks[i]); 56 | } 57 | // devolvemos el máximo 58 | return max; 59 | }; 60 | ``` 61 | 62 | Complejidad Temporal | Complejidad Espacial 63 | --|-- 64 | O(n)|O(1) 65 | 66 | ## Código 67 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/JjYI). 68 | -------------------------------------------------------------------------------- /Ejercicios/04-MultidimensionalSumArray/MultidimensionalSumArray.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | //mdArraySum([1,2,3,4]); //should return 10 4 | // 5 | //mdArraySum([ [2,4] , [1], [4,2,1] ]); //should return 14 6 | // 7 | //mdArraySum([ 2, [3,4], 5, [-3, [6 , [ 4,5 ] ] ] ]); //should return 26 8 | // 9 | 10 | function mdArraySum(array) { 11 | //Escribir la funcion 12 | } 13 | -------------------------------------------------------------------------------- /Ejercicios/04-MultidimensionalSumArray/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Multi-Dimensional SumArray 3 | ## Introducción 4 | Ya trabajamos con arreglos de una unica dimension, ahora subiremos un escalón e iremos por arreglos de dos dimensiones, es decir, un arreglo de arreglos de enteros. 5 | En este caso, el objetivo es encontrar la suma de todos los elementos del arreglo. 6 | 7 | #### Ejemplos 8 | **mdArray**: [1,2,3,4] 9 | **output**: 10 10 | 11 | **mdArraySum**: [ [2,4] , [1], [4,2,1] ] 12 | **output**: 14 13 | 14 | **mdArraySum**: [ 2, [3,4], 5, [-3, [6 , [ 4,5 ] ] ] ] 15 | **output**: 26 16 | 17 | ## Solución 18 | ### En palabras 19 | Algunas consideraciones a tener en cuenta antes de implementar una solución. 20 | 21 | 1. La suma inicial es cero 22 | 2. Chequea cada elemento en el arreglo 23 | 1. Si no es un arreglo agrégalo a la suma 24 | 2. Si es un arreglo agrega la suma de todos sus elementos a la suma 25 | 3. Devuelve el total 26 | 27 | ### Primer Alternativa 28 | Podemos empezar a implementar la solución, pero antes tenemos que resolver una pregunta: 29 | ###### ¿Cómo podemos calcular la suma en los elementos de un sub-arreglo de un sub-arreglo? La respuesta es ***RECURSIÓN*** 30 | 31 | ```javascript 32 | const mdArraySum = (arr) => { 33 | // Iniciamos la suma en 0 34 | let sum = 0; 35 | // Iteramos sobre el arreglo 36 | for (let i = 0; i < arr.length; i += 1) { 37 | // si es un arreglo le sumamos lo que devuelve llamar otra vez la función sobre ese arreglo 38 | if (Array.isArray(arr[i])) sum += mdArraySum(arr[i]) 39 | // si no le sumamos al total 40 | else sum += arr[i] 41 | } 42 | // devolvemos el total 43 | return sum; 44 | } 45 | ``` 46 | Considerando que **m es la cantidad de elementos en todos los arreglos** y **m el nivel máximo de profundidad** obtenemos los siguientes ordenes de complejidad. 47 | 48 | Complejidad Temporal | Complejidad Espacial 49 | --|-- 50 | O(n)|O(m) 51 | 52 | ### Segunda alternativa 53 | Veamos una solución one-liner. 54 | 55 | ```javascript 56 | const mdArraySum2 = arr => 57 | arr.reduce((total, elem) => total + (Array.isArray(elem) ? mdArraySum2(elem) : elem), 0) 58 | ``` 59 | 60 | ## Código 61 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/Jl9b). 62 | -------------------------------------------------------------------------------- /Ejercicios/05-MinStack/MinStack.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 5 | // 6 | 7 | function MinStack() { 8 | // Escribir la funcion 9 | } 10 | -------------------------------------------------------------------------------- /Ejercicios/05-MinStack/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Min Stack 4 | ## Introducción 5 | Para poder comprender el objetivo de esta actividad necesitamos saber **¿Qué es un stack?** Un stack, también conocido como pila es **LIFO** (Last-In First-Out), es decir, el último en entrar es el primero en salir. 6 | 7 | En este caso, el ejercicio es implementar un stack que tenga los siguientes métodos: 8 | 1. **push(value) :** añadir el elemento, value, al stack. 9 | 2. **pop ( ) :** sacar un elemento del stack. 10 | 3. **min ( ) :** obtener el elemento con el valor mínimo. 11 | 12 | #### Importante 13 | * **TODOS** los métodos mencionados anteriormente deben ser de O(1). 14 | * Para la resolución del ejercicio no se puede utilizar **ningún** *Array method* 15 | 16 | ## Solución 17 | ### En palabras 18 | 19 | 1. Implementar un stack normal 20 | 2. Luego, implementar un stack con un requisito mas > encontrar el mínimo 21 | 22 | ##### Importante 23 | 24 | **NO PUEDES** guardar el valor mínimo y cada vez que agregas un nuevo valor compararlo **¿POR QUÉ?** 25 | **( ! ) IDEA:** Tener una estructura separada para guardar el mínimo por cada nodo que se agrega, y cuando sacamos el nodo removemos ese mínimo 26 | 27 | ### Primer aproximación 28 | Una primer aproximación para la resolución de este ejercicio es realizar un stack común. 29 | 30 | ```javascript 31 | class Node{ 32 | constructor(value) { 33 | this.value = value; 34 | this.next = null; 35 | } 36 | } 37 | 38 | class Stack{ 39 | constructor(value) { 40 | this.top = null; 41 | } 42 | 43 | push(val) { 44 | if(!this.top) this.top = new Node(val); 45 | else { 46 | const newTop = new Node(val); 47 | newTop.next = this.top; 48 | this.top = newTop; 49 | } 50 | } 51 | 52 | pop() { 53 | const oldTop = this.top; 54 | this.top = oldTop && oldTop.next; 55 | return oldTop && oldTop.value; 56 | } 57 | 58 | peek() { 59 | return this.top && this.top.value 60 | } 61 | } 62 | ``` 63 | 64 | ### Extendemos el stack 65 | Luego, mejoramos la resolución previamente presentada. Extendemos el stack para agregarle el mínimo 66 | 67 | ```javascript 68 | class MinStack extends Stack{ 69 | constructor() { 70 | super(); 71 | this.minimum = new Stack(); 72 | } 73 | 74 | push(val) { 75 | if(!this.top) { 76 | this.top = new Node(val); 77 | this.minimum.push(val); 78 | } 79 | else { 80 | const newTop = new Node(val); 81 | newTop.next = this.top; 82 | this.top = newTop; 83 | if(this.minimum.peek() > val) this.minimum.push(val); 84 | else this.minimum.push(this.minimum.peek()); 85 | } 86 | } 87 | 88 | pop() { 89 | const oldTop = this.top; 90 | this.top = oldTop && oldTop.next; 91 | this.minimum.pop();return oldTop && oldTop.value; 92 | } 93 | 94 | min() { 95 | return this.minimum.peek(); 96 | } 97 | } 98 | ``` 99 | 100 | ## Complejidad Espacial 101 | La complejidad espacial del ejercicio sigue siendo de O(n) con la diferencia que ahora almacenamos el doble de la información, O(2n) 102 | 103 | ## Código 104 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/JqWw). 105 | -------------------------------------------------------------------------------- /Ejercicios/06-HasBalanceBrackets/HasBalanceBrackets.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // "{ [ ] ( ) }" debería devolver true 4 | // 5 | // "{ [ ( ] ) }" debería devolver false 6 | // 7 | // "{ [ }" debería devolver false 8 | // 9 | // "{ [ ( [ { ( )[ ]{ } } ] ) ] }" debería devolver true 10 | // 11 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 12 | function HasBalanceBrackets() { 13 | // Escribir la funcion 14 | } 15 | -------------------------------------------------------------------------------- /Ejercicios/06-HasBalanceBrackets/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Has Balance Brackets 4 | ## Introducción 5 | Crear un bracket validator. La idea es que chequee que los brackets estén balanceados correctamente. 6 | 7 | Los brackets válidos son los siguientes: **[ ] ( ) { }** 8 | 9 | ### Ejemplos 10 | 11 | **input:** "{ [ ] ( ) }" 12 | **output:** true 13 | 14 | **input:** "{ [ ( ] ) }" 15 | **output:** false 16 | 17 | **input:** "{ [ }" 18 | **output:** false 19 | 20 | **input:** "{ [ ( [ { ( )[ ]{ } } ] ) ] }" 21 | **output:** true 22 | 23 | ## Solución 24 | ### En Palabras 25 | 26 | 1. Tienes: 27 | * **"opening"** - **( { [** - y, 28 | * **"closing"** - **) } ]** - brackets. 29 | 2. Cada closing bracket tiene que corresponder con la opening bracket mas cercano que empareje. 30 | 3. Cada opening y closing bracket tienen que estar en pareja. 31 | 32 | Entonces tienen que ir trackeando los opening brackets y fijarse si cuando encontramos una closing bracket, matchea con la opening bracket mas cercana 33 | 34 | ##### ¿Qué estructura de datos podemos utilizar para esto? 35 | 36 | ### Solución posible 37 | ```javascript 38 | const hasBalancedBrackets = (string) => { 39 | // Tenemos un diccionario para chequear las opening brackets con sus closing brackets 40 | const validBrackets = { 41 | '{' : '}', 42 | '[' : ']', 43 | '(' : ')', 44 | }; 45 | // creamos un arreglo donde vamos a ir guardando los openBrackets 46 | const openBrackets = []; 47 | // iteramos sobre el string 48 | for (let i = 0; i < string.length; i += 1) { 49 | // si existe la propiedad significa que es un opening bracket entonces lo guardamos 50 | if (validBrackets[string[i]]) { 51 | openBrackets.push(string[i]); 52 | } else if (validBrackets[openBrackets.pop()] !== string[i]) { 53 | // Si no nos fijamos que el closing bracket corresponda con el ultimo opening bracket 54 | return false; 55 | } 56 | } 57 | // una vez que terminamos de recorrer 58 | // chequeamos que no haya quedado nada en el arreglo 59 | return !openBrackets.length; 60 | }; 61 | ``` 62 | 63 | ## Conclusión 64 | * Las estructuras de datos pueden ser muy útiles aunque... no estemos explícitamente creando una. 65 | * Podemos usar arreglos y métodos del arreglo para crear un arreglo que se comporte como un stack/queue 66 | 67 | ## Código 68 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/JsIz). 69 | -------------------------------------------------------------------------------- /Ejercicios/07-SolveGraph/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Solve Graph 4 | ## Introducción 5 | Un grafo/graph es un set de vertices conectados entre ellos por aristas. 6 | 7 | ### Undirected vs. Directed Graphs 8 |

9 | 10 |

11 | 12 | ### ¿Qué hay que hacer? 13 | Escribe una función que determine si existe un path entre dos vertices de un graph. 14 | 15 | El graph será representado como un objeto. Cada key representa un vértice. El valor, todos los vertices que pueden ser alcanzados. 16 | 17 | El graph, será un *'directed graph'*. 18 | 19 |

20 | 21 | Como observamos, en la imagen de la izquierda el nodo 'a' se conecta con el nodo 'b', el nodo 'b' con el nodo 'c' y 'd' y por último, el nodo 'c' con el nodo 'd'. 22 | 23 | ## Solución 24 | ### En palabras 25 | - La solución puede ser un algoritmo **Breadth-First** o **Depth-First** 26 | - Pero... los graphs pueden ser cíclicos 27 | - Si empezamos recorriendo el vértice A, eventualmente vamos a llegar al vértice R que apunta devuelta al A. 28 | 29 | ```javascript 30 | { 31 | a: ['c'], 32 | c: ['s', 'r'], 33 | r: ['a'], 34 | s: [ ] 35 | } 36 | ``` 37 | - ¿El problema? Un algoritmo normal de BFS/DFS terminaría en un **loop infinito**. 38 | - Por lo tanto, tu algoritmo tiene que traquear todos los vertices que visitó 39 | - Si un vértice ha sido visitado sabemos que no tenemos que recorrer sus aristas por segunda vez 40 | - El **algoritmo se completa** cuando se ha encontrado el target o cuando todas las posibilidades fueron recorridas. 41 | 42 | ### Solución depth-first 43 | 44 | ```javascript 45 | const graph = { 46 | a: ['c'], 47 | b: ['c'], 48 | c: ['s', 'r'], 49 | d: ['a'], 50 | s: ['a', 'c'], 51 | r: ['d'], 52 | z: ['z'] 53 | }; 54 | function solveGraphDFS(graph, start, end, visited = {}) { 55 | // nos fijamos si ya visitamos este vértice 56 | if (visited[start]) return false; 57 | // lo agregamos a los visitados 58 | visited[start] = true; 59 | // iteramos sobre el arreglo de vértices 60 | for (let i = 0; i < graph[start].length; i += 1) { 61 | // Si encontramos el target devolvemos true 62 | if (end === graph[start][i]) return true; 63 | // si no llamamos recursivamente a la función para ver si sus aristas están conectadas 64 | else if (solveGraphDFS(graph, graph[start][i], end, visited)) return true 65 | } 66 | // si no devolvemos false 67 | return false; 68 | } 69 | 70 | solveGraphDFS(graph, 'a', 'r') // true 71 | solveGraphDFS(graph, 's', 'b') // false 72 | ``` 73 | 74 | Complejidad Temporal | Complejidad Espacial 75 | --|-- 76 | O(n)|O(n) 77 | 78 | 79 | ### Solución breadth-first approach 80 | ```javascript 81 | const graph = { 82 | a: ['c'], 83 | b: ['c'], 84 | c: ['s', 'r'], 85 | d: ['a'], 86 | s: ['a', 'c'], 87 | r: ['d'], 88 | z: ['z'] 89 | }; 90 | function solveGraphBFS(graph, start, end, visited = {}, queue = []) { 91 | // nos fijamos si ya visitamos este vértice 92 | if (visited[start]) return false; 93 | // lo agregamos a los visitados 94 | visited[start] = true; 95 | // iteramos sobre el arreglo de vértices 96 | for (let i = 0; i < graph[start].length; i += 1) { 97 | // agregamos todas sus conexiones al queue 98 | queue.push(graph[start][i]); 99 | } 100 | // comparamos si el siguiente del queue es nuestro target 101 | // sino llamamos recursivamente a la función con el start del siguiente del queue 102 | return queue[0] === end || solveGraphBFS(graph, queue.shift(), end, visited, queue); 103 | } 104 | solveGraphBFS(graph, 'a', 'r'); // true 105 | solveGraphBFS(graph, 's', 'b'); // false 106 | ``` 107 | Complejidad Temporal | Complejidad Espacial 108 | --|-- 109 | O(n)|O(n) 110 | 111 | ## Código 112 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/JuS9). 113 | -------------------------------------------------------------------------------- /Ejercicios/07-SolveGraph/SolveGraph.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 5 | 6 | function SolveGraph(obj, vertice, vertice2) { 7 | // Escribir la funcion 8 | } 9 | -------------------------------------------------------------------------------- /Ejercicios/08-FindWordStartingWith/FindWordStartingWith.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // const book = { 3 | // id: 1, 4 | // text: 'Erase una vez un libro de palabras que era un poco aburrido pero tenia much 5 | // } 6 | // findWordsStartingWith(book, 'de') // [23, 112] 7 | // findWordsStartingWith(book, 'un') // [ 6, 14, 43, 99, 115 ] 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 9 | 10 | function FindWordStartingWith() { 11 | // Escribir la funcion 12 | } 13 | -------------------------------------------------------------------------------- /Ejercicios/08-FindWordStartingWith/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Find Word Starting With 4 | ## Introducción 5 | Dado un "libro" y un string para buscar, devolver todos los indices donde la palabra empieza con ese string. 6 | 7 | El libro vendrá con dos cosas: un id y un texto. **La búsqueda tiene que ser case insensitive.** 8 | 9 | #### Ejemplo 10 | ```javascript 11 | const book = { 12 | id: 1, 13 | text: 'Erase una vez un libro de palabras que era un poco aburrido pero tenia muchas' 14 | } 15 | ``` 16 | 17 | findWordsStartingWith **(book, 'de')** 18 | **output:** [23] 19 | 20 | findWordsStartingWith **(book, 'un')** 21 | **output:** [ 6, 14, 43] 22 | 23 | 24 | ## Solución 25 | ### Primer alternativa 26 | Una alternativa, **naive**, es iterar a través del texto. 27 | ```javascript 28 | const findWordsStartingWithNaive = (book, query) => { 29 | const separators = { 30 | ' ': true, 31 | '.': true, 32 | ',': true, 33 | } 34 | const text = book.text.toLowerCase(); 35 | const finds = []; 36 | for (let i = 0; i < text.length; i += 1) { 37 | if (i !== 0 && !separators[text[i-1]]) continue; 38 | for (let j = 0; j < query.length; j += 1) { 39 | if (query[j] !== text[i + j]) { 40 | i += j; 41 | break; 42 | } 43 | if (j === query.length - 1){ 44 | finds.push(i); 45 | i += j; 46 | } 47 | } 48 | } 49 | return finds; 50 | } 51 | ``` 52 | **Complejidad temporal:** O(n) 53 | 54 | ### Segunda Alternativa 55 | Otra alternativa, es utilizar un **trie**. Pero ... ¿Que es un trie? 56 | 57 | #### Ejemplo 58 | ```javascript 59 | { 60 | [char]: { 61 | data: data, 62 | [nextChar]: { 63 | data: data, 64 | // ... 65 | } 66 | } 67 | } 68 | ``` 69 | ###### ¿Podes encontrar el mensaje secreto? 70 | 71 | ```javascript 72 | const trie = { 73 | t: { 74 | indexes: [0, 5], 75 | o: { 76 | indexes:[0, 5], 77 | n: { 78 | indexes: [0, 5], 79 | i: { 80 | indexes: [0] 81 | }, 82 | t: { 83 | indexes: [5], 84 | o:{ 85 | indexes: [5] 86 | } 87 | } 88 | } 89 | } 90 | } 91 | } 92 | ``` 93 | ###### Equivale a: 94 | ```javascript 95 | buildTrie('Toni tonto') 96 | ``` 97 | 98 | #### ¿Por qué? 99 | Porque **repetir la ejecución va a ser mucho mas rápido con un árbol**. 100 | 101 | 102 | ### Paso 1: Haz el TRIE 103 | ```javascript 104 | const buildTrie = (text) => { 105 | const trie = {}; 106 | const separators = { 107 | ' ': true, 108 | '.': true, 109 | ',': true, 110 | } 111 | for (let i = 0; i < text.length; i += 1) { 112 | let currentLetter = trie; 113 | const startingIndex = i; 114 | while(text[i] && !separators[text[i]]) { 115 | currentLetter[text[i]] = currentLetter[text[i]] || { indexes: [] } 116 | currentLetter = currentLetter[text[i]]; 117 | currentLetter.indexes.push(startingIndex); 118 | i++; 119 | } 120 | } 121 | return trie; 122 | }; 123 | ``` 124 | ### Paso 2: 125 | Una vez que el TRIE es creado todo lo que necesitas hacer es **iterar a través del largo del string**, **recorrer los nodos hasta** que llegues al **final** y luego, **retornar el arreglo de indices en ese punto**. 126 | 127 | ```javascript 128 | const tries = {}; 129 | const findOrCreateTrie = ({ id, text }) => { 130 | tries[id] = tries[id] || buildTrie(text); 131 | return tries[id]; 132 | }; 133 | 134 | const findWordsStartingWith = (book, query) => { 135 | const trie = findOrCreateTrie(book) 136 | let currentLetter = trie; 137 | query = query.toLowerCase(); 138 | for (let i = 0; i < query.length && currentLetter; i++) { 139 | currentLetter = currentLetter[query[i]] 140 | } 141 | return currentLetter ? currentLetter.indexes: []; 142 | } 143 | ``` 144 | 145 | ## Complejidad 146 | ### Buscar si hay que construir el TRIE 147 | Complejidad Temporal | Complejidad Espacial 148 | --|-- 149 | O(n+m)|O(1) 150 | 151 | ### Buscar si el TRIE ya fue construido 152 | Complejidad Temporal | Complejidad Espacial 153 | --|-- 154 | O(m)|O(1 155 | 156 | ## Código 157 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/JvdR/9). 158 | -------------------------------------------------------------------------------- /Ejercicios/09-BinaryToDecimal/BinaryToDecimal.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | // 5 | // 6 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 7 | 8 | function BinaryToDecimal() { 9 | // Escribir la funcion 10 | } 11 | -------------------------------------------------------------------------------- /Ejercicios/09-BinaryToDecimal/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Binary to Decimal 4 | ## Introducción 5 | Escribe una función que pase un string en binario a un número decimal 6 | 7 | ## Solución 8 | ### En palabras 9 | 1. Iterar sobre cada número 10 | 2. Ir sumando: la potencia de 2 y, su posición, multiplicada por el número [1 ó 0]. 11 | 12 | #### Ejemplo 13 |

14 | 15 |

16 | 17 | ### Primer alternativa 18 | ```javascript 19 | const binaryToDecimal = (binary) => { 20 | let sum = 0; 21 | for (let i = 0; i < binary.length; i += 1) { 22 | sum += Math.pow(2, binary.length - (i+1)) * binary[i]; 23 | } 24 | return sum; 25 | }; 26 | ``` 27 | 28 | ### Segunda alternativa 29 | En este caso, se propone una **solución recursiva**. 30 | ```javascript 31 | const binaryToDecimalRec = (binary) => { 32 | const sum = Math.pow(2, binary.length - 1) * binary[0] 33 | if (binary.length !== 1) { 34 | return sum + binaryToDecimalRec(binary.slice(1)); 35 | } 36 | return sum 37 | } 38 | ``` 39 | 40 | ## Código 41 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KBgB/4). 42 | -------------------------------------------------------------------------------- /Ejercicios/10-DecimalToBynary/DecimalToBynary.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // 4 | // 5 | // 6 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 7 | 8 | function DecimalToBynary() { 9 | // Escribir la funcion 10 | } 11 | -------------------------------------------------------------------------------- /Ejercicios/10-DecimalToBynary/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Decimal to Binary 4 | ## Introducción 5 | En el caso anterior transformábamos números binarios en decimales. En este caso hay que **hacer una función que tome un numero decimal y lo devuelva en binario** 6 | 7 | ## Solución 8 | ### En palabras 9 | 1. Tomá el número y sacá su modulo en 2 10 | 2. Guardá el resultado en un string 11 | 3. Dividí el número por 2 y redondealo para abajo 12 | 4. Continúa el proceso hasta que el número sea igual a 0 13 | 5. Devuelve el string 14 | 15 | ### Primer alternativa 16 | ```javascript 17 | const decimalToBinary = (num) => { 18 | let binary = ''; 19 | while(num) { 20 | binary = num % 2 + binary; 21 | num = Math.floor(num / 2); 22 | } 23 | return binary 24 | } 25 | ``` 26 | ### Segunda alternativa 27 | En este caso, se propone una **solución recursiva**. 28 | ```javascript 29 | const decimalToBinaryRec = (num) => { 30 | if (num) { 31 | return decimalToBinaryRec(Math.floor(num / 2)) + num % 2 32 | } 33 | return ''; 34 | } 35 | ``` 36 | ## Código 37 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KDLz/1). 38 | -------------------------------------------------------------------------------- /Ejercicios/11-ClockMinuteAdder/ClockMinuteAdder.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // clockMinuteAdder('09:00', 20); // '09:20' 4 | // 5 | // clockMinuteAdder('01:30', 30); // '02:00' 6 | // 7 | // clockMinuteAdder('12:05', 100); // '01:45' 8 | // 9 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 10 | 11 | function clockMinuteAdder() { 12 | // Escribir la funcion 13 | } 14 | -------------------------------------------------------------------------------- /Ejercicios/11-ClockMinuteAdder/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Clock minute adder 4 | ## Introducción 5 | Dada una hora en string en **formato HH:MM**, y un número de minutos. 6 | Devolver la nueva hora pasados esos minutos. 7 | 8 | ##### IMPORTANTE 9 | El reloj es de 12 horas y tiene que devolverse en el formato HH:MM. Recuerda que no existen las 00hs. 10 | 11 | ##### Ejemplos: 12 | clockMinuteAdder (**'09:00', 20**); 13 | **ouput**: '09:20' 14 | 15 | clockMinuteAdder (**'01:30', 30**); 16 | **ouput**: '02:00' 17 | 18 | clockMinuteAdder (**'12:05', 100**); 19 | **ouput**: '01:45' 20 | 21 | ## Solución 22 | ```javascript 23 | const clockMinuteAdder = (time, minutesToAdd) => { 24 | // Separo las horas y los minutos 25 | const [hours, minutes] = time.split(':'); 26 | 27 | // agrego el total de minutos y el total de horas 28 | const totalMinutes = (minutesToAdd + parseInt(minutes)); 29 | const totalHours = Math.floor(totalMinutes/60) + parseInt(hours); 30 | 31 | // saco las nuevas horas y minutos 32 | const newHours = ((totalHours - 1) % 12) + 1 ; // para que no quede 0hrs 33 | const newMinutes = totalMinutes % 60; 34 | 35 | // le agrego formato de ceros adelante si es necesario 36 | const formatHours = newHours > 9 ? newHours : `0${newHours}`; 37 | const formatMinutes = newMinutes > 9 ? newMinutes : `0${newMinutes}`; 38 | 39 | //devuelvo la nueva hora 40 | return `${formatHours}:${formatMinutes}`; 41 | }; 42 | ``` 43 | 44 | ## Código 45 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KEvy/3). 46 | -------------------------------------------------------------------------------- /Ejercicios/12-Intersection/Intersection.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Ej: [1,3,5,7,10], [2,3,6,8,10,20] => [3, 10] 4 | // 5 | // 6 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 7 | 8 | function intersection() { 9 | // Escribir la funcion 10 | } 11 | -------------------------------------------------------------------------------- /Ejercicios/12-Intersection/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Intersection 3 | ## Introducción 4 | Dado dos arreglos **ordenados** devuelve un 5 | arreglo con los números que se repiten. 6 | 7 | #### Ejemplos: 8 | **input**: [1,3,5,7,10], [2,3,6,8,10,20] 9 | **output**: [3, 10] 10 | 11 | ## Solución 12 | ### Primer alternativa: Fuerza Bruta 13 | ```javascript 14 | function intersection(arr1, arr2) { 15 | const result = []; 16 | arr1.forEach(num1 => { 17 | arr2.forEach(num2 => { 18 | if(num1 === num2) result.push(num1); 19 | }); 20 | }); 21 | return result; 22 | } 23 | ``` 24 | Complejidad Temporal | Complejidad Espacial 25 | --|-- 26 | O(n*m)|O(n) 27 | 28 | ### Segunda alternativa: Solución Optima 29 | ```javascript 30 | function intersection2(arr1, arr2) { 31 | let index1 = 0; 32 | let index2= 0; 33 | const result = []; 34 | while(index1 < arr1.length && index2 < arr2.length) { 35 | if (arr1[index1] === arr2[index2]) { 36 | result.push(arr1[index1]); 37 | index1 += 1; 38 | index2 += 1; 39 | } 40 | else if(arr1[index1] < arr2[index2]) index1 += 1; 41 | else index2 += 1 42 | } 43 | return result; 44 | } 45 | ``` 46 | Complejidad Temporal | Complejidad Espacial 47 | --|-- 48 | O(n+m)|O(n) 49 | 50 | 51 | ###### Pero... ¿Qué pasaría si el arreglo no estuviese ordenado? 52 | 53 | ### Para un arreglo desordenado 54 | ```javascript 55 | function intersection3(arr1, arr2) { 56 | const hashMap = arr1.reduce((memo, num) => { 57 | memo[num] = true; 58 | return memo; 59 | }, {}); 60 | return arr2.filter(num => hashMap[num]); 61 | } 62 | ``` 63 | Complejidad Temporal | Complejidad Espacial 64 | --|-- 65 | O(n+m)|O(n) 66 | 67 | Como verán, la complejidad espacial sigue siendo O(n) **pero estamos creando n de espacio extra por el HashMap**. 68 | 69 | ## Código 70 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KKep/1). 71 | -------------------------------------------------------------------------------- /Ejercicios/13-SubSetSum/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Subset Sum 3 | ## Introducción 4 | Dada una suma objetiva, 'target' y un arreglo de números positivos: 5 | * Devolvé **true** si cualquier combinación de números en el arreglo suma el target. 6 | * Devolvé **false** si los números no pueden ser usados para sumar el target 7 | 8 | ##### IMPORTANTE 9 | Cada número en el arreglo solo se puede usar una vez. 10 | 11 | #### Ejemplos: 12 | subsetSum( **[1,10,5,3], 9** ); 13 | **output**: true <= 1 + 5 + 3 14 | 15 | subsetSum( **[1,10,5,3], 19** ); 16 | **output**:true <= add all 4 17 | 18 | subsetSum( **[1,10,5,3], 17** ); 19 | **output**:false 20 | 21 | subsetSum( **[1,10,5,3], 2** ); 22 | **output**:false 23 | 24 | subsetSum( **[1,10,5,3], 10** ); 25 | **output**:true <= 10 + 0 = 10 26 | 27 | ## Solución 28 | ### Primer alternativa: Iterativa 29 | #### En palabras 30 | Construir un arreglo de todas las sumas posibles: 31 | 1. Inicializa el arreglo de sumas con 0 32 | 2. Itera sobre el arreglo de números 33 | 3. Itera sobre el arreglo de sumas, chequeando si el elemento actual + la suma es igual al target 34 | 4. Si la nueva suma es menor que el target 35 | guardalo en el arreglo de sumas 36 | 37 | ##### Ejemplo: 38 | ```javascript 39 | subsetSum(17, [1, 10, 5, 3]) 40 | => set de posibles sumas: [0] 41 | => agrega 1 a cada suma posible 42 | => set de posibles sumas: [0, 1] 43 | => agrega 10 a cada suma posible 44 | => set de sumas posibles: [0, 1, 10, 11] 45 | => agrega 5 a cada posible suma 46 | => set de sumas posibles: [0, 1, 10, 11, 5, 6, 15, 16] 47 | ``` 48 | 49 | #### En código 50 | ```javascript 51 | const subsetSum = (nums, target) => { 52 | const sums = [0]; 53 | return nums.some((num) => { 54 | const copySums = [...sums]; 55 | return copySums.some(sum => { 56 | const newSum = sum + num; 57 | if (target === newSum) return true; 58 | if (newSum < target) sums.push(newSum); 59 | }) 60 | }) 61 | } 62 | ``` 63 | 64 | ### Segunda alternativa: Optimización 65 | Con la alternativa anterior... Podemos estar agregando valores repetidos al arreglo que nos dan el mismo resultado 66 | 67 | ##### Ejemplo 68 | ```javascript 69 | => 1,2,3,4,5,6 70 | => 0,1,2,3,3,4,5,6,4,5,6,7 71 | ``` 72 | 73 | ###### ¿Como podemos evitar agregar elementos repetidos sin agregar complejidad? Con UN SET. 74 | 75 | #### Solución Iterativa con Set 76 | ```javascript 77 | const subsetSumSet = (nums, target) => { 78 | const sums = new Set([0]); 79 | return nums.some((num) => { 80 | const copySums = [...sums]; 81 | for (let sum of copySums) { 82 | const newSum = sum + num; 83 | if (target === newSum) return true; 84 | if (newSum < target) sums.add(newSum); 85 | } 86 | }) 87 | } 88 | ``` 89 | 90 | ### Tercer Alternativa: Solución Recursiva 91 | #### En palabras 92 | También podemos encarar este problema recursivamente. 93 | 94 | Por cada elemento del arreglo solo nos importa: 95 | 96 | 1. Usarlo para construir la suma nos va a ayudar a llegar al target 97 | 2. Saltearlo y añadir otros números va a hacernos llegar al target 98 | 3. Entonces... por cada elemento, hagamos una llamada recursiva que chequeé estas dos cosas 99 | 100 | #### En código 101 | ```javascript 102 | const subsetSumRec = (nums, target, index = 0) => { 103 | if (target === 0) return true; 104 | if (target < 0) return false; 105 | if (index > nums.length) return false; 106 | const whenExcluded = subsetSumRec(nums, target, index + 1) 107 | const whenIncluded = subsetSumRec(nums, target - nums[index], index + 1); 108 | return whenExcluded || whenIncluded 109 | } 110 | ``` 111 | 112 | ###### Pero de nuevo estamos creando muchos caminos que se repiten... 113 | 114 | 115 | #### Optimización de la Solución Recursiva 116 | Con memoization podemos guardar los números que ya tuvimos un resultado y no tener que volver a procesarlos. 117 | 118 | ```javascript 119 | const subsetSumRecMemo = (nums, target, index = 0, memo = {}) => { 120 | if(memo.hasOwnProperty(target)) return memo[target]; 121 | if (target === 0) return true; 122 | if (target < 0) return false; 123 | if (index > nums.length) return false; 124 | const whenIncluded = subsetSumRec(nums, target - nums[index], index + 1); 125 | const whenExcluded = subsetSumRec(nums, target, index + 1); 126 | memo[target] = whenExcluded; 127 | memo[target - nums[index]] = whenIncluded; 128 | return whenExcluded || whenIncluded ; 129 | } 130 | ``` 131 | ## Complejidad 132 | Todas las soluciones son de complejidad: 133 | 134 | Complejidad Temporal | Complejidad Espacial 135 | --|-- 136 | O(2^n)|O(2^n) 137 | 138 | Aunque algunas sean mas óptimas que otras, en el peor de los casos, hay que recorrer todo el arreglo, y no tener ninguna suma repetida. 139 | 140 | ## Código 141 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KM8S/4). 142 | -------------------------------------------------------------------------------- /Ejercicios/13-SubSetSum/SubSetSum.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // subsetSum(9, [1, 10, 5, 3]); // true, 1 + 5 + 3 3 | // 4 | // subsetSum(19, [1, 10, 5, 3]); // true, add all 4 5 | // 6 | // subsetSum(17, [1, 10, 5, 3]); // false 7 | // 8 | // subsetSum(2, [1, 10, 5, 3]); // false 9 | // 10 | // subsetSum(10, [1, 10, 5, 3]); // true, since 10 + 0 = 10 11 | // 12 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 13 | 14 | function subsetSum(n, array) { 15 | // Escribir la funcion 16 | } 17 | -------------------------------------------------------------------------------- /Ejercicios/14-LongestIncreasingSubSequence/LongestIncreasingSubSequence.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // longestIncreasingSubsequence([3, 4, 2, 1, 10, 6]); 4 | // debería devolver 3: 5 | // 3, 4, 6 6 | // 7 | // longestIncreasingSubsequence([10, 22, 9, 33, 20, 50, 41, 60, 80]); 8 | // debería devolver 6: 9 | // 10, 22, 33, 41, 60, 80 (or 10, 22, 33, 50, 60, 80) 10 | // 11 | // longestIncreasingSubsequence([10, 22, 9, 33, 20, 50, 41, 60, 80, 21, 23, 24, 25, 26, 27, 28]); 12 | // debería devolver 9: 13 | // 10, 20, 21, 23, 24, 25, 26, 27, 28 14 | // 15 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | function longestIncreasingSubsequence() { 18 | // Escribir la funcion 19 | } 20 | -------------------------------------------------------------------------------- /Ejercicios/14-LongestIncreasingSubSequence/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Longest Increasing Subsequence 3 | ## Introducción 4 | Dado un arreglo de números, encontrá el length de la secuencia creciente mas larga posible. Esta secuencia puede saltear números en el arreglo. 5 | 6 | #### Ejemplos 7 | **input:** [3,10,4,5] 8 | La **secuencia es [3,4,5]** 9 | **output:** 3. 10 | 11 | 12 | longestIncreasingSubsequence(**[3, 4, 2, 1, 10, 6]**); 13 | Donde la **secuencia** es: 3, 4, 6 14 | **output**: 3 15 | 16 | 17 | longestIncreasingSubsequence(**[10, 22, 9, 33, 20, 50, 41, 60, 80]**); 18 | Donde la **secuencia** es: 10, 22, 33, 41, 60, 80 (or 10, 22, 33, 50, 60, 80) 19 | **output**: 6 20 | 21 | longestIncreasingSubsequence(**[10, 22, 9, 33, 20, 50, 41, 60, 80, 21, 23, 24, 25, 26, 27, 28]**); 22 | Donde, la **secuencia** es: 10, 20, 21, 23, 24, 25, 26, 27, 28 23 | **output**: 9 24 | 25 | ## Solución 26 | ### Primer Alterantiva: Fuerza Bruta 27 | Recorrer todas las posibilidades de subsecuencias y quedarse con la mas grande. 28 | 29 | ```javascript 30 | function IterativeLIS (nums) { 31 | const sequences = [[-Infinity]]; 32 | nums.forEach(num => { 33 | const copySeq = [...sequences]; 34 | copySeq.forEach(sequence => { 35 | if(sequence.slice(-1)[0] < num) sequences.push([...sequence, num]); 36 | }); 37 | }); 38 | return sequences.reduce((memo, seq) => { 39 | if (memo > seq.length) return memo; 40 | return seq.length; 41 | }, 1) -1; 42 | } 43 | ``` 44 | 45 | Recorrer todas las posibilidades de subsecuencias incluyendo o no incluyendo ese número 46 | ```javascript 47 | function longestIncreasingSubsequence (nums, index = 0, base = -Infinity) { 48 | // si ya recorrimos todo el arreglo devolver cero ya que termino la secuencia 49 | if (index === nums.length) return 0; 50 | // sacar la longitud de la secuencia que llego cuando le numero es excluido 51 | const whenExcluded = longestIncreasingSubsequence(nums, index + 1, base); 52 | // fijarse si el numero es menor que el numero que llega en la base 53 | // si es menor directamente devolver el excluido 54 | if (nums[index] <= base) return whenExcluded; 55 | // Tomar el valor cuando es incluido en la secuencia sumandole uno por si mismo 56 | const whenIncluded = 1 + longestIncreasingSubsequence(nums, index + 1, nums[index]); 57 | // devolver el mayor entre el incluido y el no incluido 58 | return Math.max(whenIncluded, whenExcluded); 59 | } 60 | ``` 61 | 62 | #### Complejidad Temporal 63 | La complejidad de tiempo de esta solución es **O(2^n)**. 64 | 65 | Pero, siempre que tomamos el **whenIncluded** de un elemento ese valor es siempre el mismo... ¿Por qué no lo guardamos? **Memoization FTW** 66 | 67 | ### Segunda Alternativa: Solución con Memoization 68 | ```javascript 69 | function memoLis (nums, index = 0, base = -Infinity, memo = {}) { 70 | if (index === nums.length) return 0; 71 | const whenExcluded = memoLis(nums, index + 1, base, memo); 72 | if (nums[index] <= base) return whenExcluded; 73 | let whenIncluded; 74 | if(memo.hasOwnProperty(index)) whenIncluded = memo[index] 75 | else { 76 | whenIncluded = 1 + memoLis(nums, index + 1, nums[index], memo); 77 | memo[index] = whenIncluded; 78 | } 79 | return Math.max(whenIncluded, whenExcluded); 80 | } 81 | ``` 82 | Fijense que **solo guardamos el whenIncluded**, ya que en el excluido la base puede ser distinta y dar distintos resultados. 83 | 84 | #### Complejidad Temporal 85 | En este caso, la complejidad temporal es de **O(n^2)**. ¿Por qué? Porque por cada elemento recorremos solo una vez en todos los elementos. 86 | 87 | ## Código 88 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KOFI/4). 89 | -------------------------------------------------------------------------------- /Ejercicios/15-SpyOn/README.md: -------------------------------------------------------------------------------- 1 | 2 | # spyOn 3 | ## Introducción 4 | Implementa tu propia versión de la función **spyOn** que hace lo siguiente: 5 | - Toma una función como parámetro 6 | - Devuelve una función spy que toma cualquier numero de argumentos 7 | - spy llama a la función y devuelve lo que ella devuelve 8 | - spy tiene los siguientes métodos: 9 | - **.getCallCount()**: Devuelve la cantidad de veces que el spy fue llamado 10 | - **.wasCalledWith(val)**: devuelve true si la función fue alguna vez llamada con ese valor, else false 11 | - **.returned(val)**: devuelve true si alguna vez devolvió ese valor. 12 | 13 | #### Ejemplos: 14 | ```javascript 15 | function adder(n1, n2) { return n1 + n2; } 16 | 17 | const adderSpy = spyOn( adder ); 18 | 19 | adderSpy.getCallCount(); // 0 20 | 21 | adderSpy(2, 4); // returns 6 22 | adderSpy.getCallCount(); // 1 23 | 24 | adderSpy(3, 5); // returns 8 25 | adderSpy.getCallCount(); // 2 26 | adderSpy.wasCalledWith(2); // true 27 | adderSpy.wasCalledWith(0); // false 28 | adderSpy.returned(6); // true 29 | adderSpy.returned(9); // false 30 | ``` 31 | 32 | ## Solución 33 | ```javascript 34 | const spyOn = (fn) => { 35 | let callCount = 0; 36 | const calledWith = new Set(); 37 | const returns = new Set(); 38 | const spy = (...args) => { 39 | callCount += 1; 40 | args.forEach(arg => calledWith.add(arg)); 41 | const result = fn(...args); 42 | returns.add(result); 43 | return result; 44 | } 45 | spy.getCallCount = () => callCount; 46 | spy.wasCalledWith = (val) => calledWith.has(val); 47 | spy.returned = (val) => returns.has(val); 48 | return spy; 49 | } 50 | ``` 51 | 52 | ## Código 53 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KUom). 54 | -------------------------------------------------------------------------------- /Ejercicios/15-SpyOn/SpyOn.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // function adder(n1, n2) { 4 | // return n1 + n2; 5 | // } 6 | // const adderSpy = spyOn(adder); 7 | // adderSpy.getCallCount(); // 0 8 | // adderSpy(2, 4); // returns 6 9 | // adderSpy.getCallCount(); // 1 10 | // adderSpy(3, 5); // returns 8 11 | // adderSpy.getCallCount(); // 2 12 | // adderSpy.wasCalledWith(2); // true 13 | // adderSpy.wasCalledWith(0); // false 14 | // adderSpy.returned(6); // true 15 | // adderSpy.returned(9); // false 16 | // 17 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 18 | 19 | function spyOn() { 20 | // Escribir la funcion 21 | } 22 | -------------------------------------------------------------------------------- /Ejercicios/16-Curry/Curry.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // function calcAllFour(var1, var2, var3, var4) { 4 | // return var1 + var2 - var3 * var4; 5 | // } 6 | // const curriedDoSomething = curry(calcAllFour); //argumentos -> [] 7 | // const firstReturn = curriedDoSomething(1); // argumentos -> [1] 8 | // const secondReturn = firstReturn(2); // argumentos -> [1, 2] 9 | // const thirdReturn = secondReturn(3); // argumentos -> [1, 2, 3] 10 | // const fourthReturn = thirdReturn(4); // -9 -> (1 + 2 - 3 * 4) 11 | // 12 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 13 | 14 | function Curry() { 15 | // Escribir la funcion 16 | } 17 | -------------------------------------------------------------------------------- /Ejercicios/16-Curry/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Curry 3 | ## Introducción 4 | ¿Que es **currying**? Consiste en **transformar una función** que utiliza múltiples argumentos en una secuencia de funciones que utilizan un único argumento. 5 | 6 | #### Ejemplos 7 | ```javascript 8 | function calcAllFour(var1, var2, var3, var4) { 9 | return var1 + var2 - var3 * var4; 10 | } 11 | const curriedDoSomething = curry(calcAllFour); //argumentos -> [] 12 | const firstReturn = curriedDoSomething(1); // argumentos -> [1] 13 | const secondReturn = firstReturn(2); // argumentos -> [1, 2] 14 | const thirdReturn = secondReturn(3); // argumentos -> [1, 2, 3] 15 | const fourthReturn = thirdReturn(4); // -9 -> (1 + 2 - 3 * 4) 16 | ``` 17 | 18 | ## Solución 19 | ### En palabras 20 | Ahora haz el Curry: 21 | - Implementa la función "curry" 22 | - Mantén en mente 23 | - Tenés que saber cuantos argumentos la función que estas 'curring' toma. 24 | - La función anterior tenía 4 parámetros 25 | - La función que devuelvas del "curring" tiene acumuladas los argumentos anteriores. 26 | - La función debe determinar si los argumentos acumulados son iguales al numero de parámetros que la función original requiere, y devolver lo que la función original devolvería con los argumentos acumulados. 27 | 28 | ### Primer Alternativa: Solución ES5 29 | ```javascript 30 | function curry(fn) { 31 | return function curriedFn() { 32 | var args = [].slice.call(arguments); 33 | if (args.length >= fn.length) { 34 | return fn.apply(null, args); 35 | } else { 36 | return function resolver() { 37 | return curriedFn.apply(null, args.concat([].slice.call(arguments))); 38 | }; 39 | } 40 | }; 41 | }; 42 | ``` 43 | 44 | ### Segunda Alternativa: Solución ES6 45 | ```javascript 46 | const curry = (fn) => { 47 | return function curriedFn(...args) { 48 | if (args.length >= fn.length) return fn(...args); 49 | else return (...nextArgs) => curriedFn(...args, ...nextArgs); 50 | }; 51 | }; 52 | ``` 53 | 54 | ## Código 55 | Pueden encontrar las soluciones recién mencionadas en el siguiente [link](https://repl.it/KWvq/1). 56 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/clover.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/coverage-final.json: -------------------------------------------------------------------------------- 1 | {"/home/alemendoza/SoyHenry/reactoTesting/problems/bracketValidator.js": {"path":"/home/alemendoza/SoyHenry/reactoTesting/problems/bracketValidator.js","statementMap":{"0":{"start":{"line":9,"column":0},"end":{"line":27,"column":1}},"1":{"start":{"line":11,"column":20},"end":{"line":15,"column":5}},"2":{"start":{"line":16,"column":24},"end":{"line":16,"column":26}},"3":{"start":{"line":17,"column":4},"end":{"line":25,"column":5}},"4":{"start":{"line":17,"column":17},"end":{"line":17,"column":18}},"5":{"start":{"line":18,"column":8},"end":{"line":24,"column":22}},"6":{"start":{"line":19,"column":12},"end":{"line":19,"column":39}},"7":{"start":{"line":21,"column":13},"end":{"line":24,"column":22}},"8":{"start":{"line":22,"column":12},"end":{"line":22,"column":25}},"9":{"start":{"line":24,"column":13},"end":{"line":24,"column":22}},"10":{"start":{"line":26,"column":4},"end":{"line":26,"column":31}}},"fnMap":{"0":{"name":"bracketValidator","decl":{"start":{"line":9,"column":26},"end":{"line":9,"column":42}},"loc":{"start":{"line":9,"column":51},"end":{"line":27,"column":1}},"line":9}},"branchMap":{"0":{"loc":{"start":{"line":18,"column":8},"end":{"line":24,"column":22}},"type":"if","locations":[{"start":{"line":18,"column":8},"end":{"line":24,"column":22}},{"start":{"line":18,"column":8},"end":{"line":24,"column":22}}],"line":18},"1":{"loc":{"start":{"line":21,"column":13},"end":{"line":24,"column":22}},"type":"if","locations":[{"start":{"line":21,"column":13},"end":{"line":24,"column":22}},{"start":{"line":21,"column":13},"end":{"line":24,"column":22}}],"line":21}},"s":{"0":1,"1":4,"2":4,"3":4,"4":4,"5":27,"6":16,"7":11,"8":2,"9":9,"10":2},"f":{"0":4},"b":{"0":[16,11],"1":[2,9]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"121007457739d27a8d05c936043786fa0f00710c"} 2 | ,"/home/alemendoza/SoyHenry/reactoTesting/problems/indexArray.js": {"path":"/home/alemendoza/SoyHenry/reactoTesting/problems/indexArray.js","statementMap":{"0":{"start":{"line":15,"column":0},"end":{"line":29,"column":3}},"1":{"start":{"line":17,"column":4},"end":{"line":26,"column":5}},"2":{"start":{"line":17,"column":29},"end":{"line":17,"column":30}},"3":{"start":{"line":19,"column":6},"end":{"line":25,"column":7}},"4":{"start":{"line":19,"column":29},"end":{"line":19,"column":30}},"5":{"start":{"line":22,"column":8},"end":{"line":22,"column":81}},"6":{"start":{"line":22,"column":75},"end":{"line":22,"column":81}},"7":{"start":{"line":24,"column":8},"end":{"line":24,"column":68}},"8":{"start":{"line":24,"column":47},"end":{"line":24,"column":68}},"9":{"start":{"line":28,"column":4},"end":{"line":28,"column":14}}},"fnMap":{"0":{"name":"findNeedle","decl":{"start":{"line":15,"column":27},"end":{"line":15,"column":37}},"loc":{"start":{"line":15,"column":56},"end":{"line":29,"column":3}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":8},"end":{"line":22,"column":81}},"type":"if","locations":[{"start":{"line":22,"column":8},"end":{"line":22,"column":81}},{"start":{"line":22,"column":8},"end":{"line":22,"column":81}}],"line":22},"1":{"loc":{"start":{"line":24,"column":8},"end":{"line":24,"column":68}},"type":"if","locations":[{"start":{"line":24,"column":8},"end":{"line":24,"column":68}},{"start":{"line":24,"column":8},"end":{"line":24,"column":68}}],"line":24}},"s":{"0":1,"1":2,"2":2,"3":18,"4":18,"5":24,"6":17,"7":7,"8":1,"9":1},"f":{"0":2},"b":{"0":[17,7],"1":[1,6]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"b200153bafd513e4dff3b4b979ea5610e161cc20"} 3 | ,"/home/alemendoza/SoyHenry/reactoTesting/problems/mayorGanancia.js": {"path":"/home/alemendoza/SoyHenry/reactoTesting/problems/mayorGanancia.js","statementMap":{"0":{"start":{"line":5,"column":0},"end":{"line":18,"column":1}},"1":{"start":{"line":6,"column":22},"end":{"line":6,"column":57}},"2":{"start":{"line":7,"column":4},"end":{"line":16,"column":5}},"3":{"start":{"line":7,"column":17},"end":{"line":7,"column":18}},"4":{"start":{"line":8,"column":8},"end":{"line":14,"column":9}},"5":{"start":{"line":8,"column":21},"end":{"line":8,"column":26}},"6":{"start":{"line":9,"column":36},"end":{"line":9,"column":71}},"7":{"start":{"line":11,"column":12},"end":{"line":13,"column":13}},"8":{"start":{"line":12,"column":16},"end":{"line":12,"column":48}},"9":{"start":{"line":17,"column":4},"end":{"line":17,"column":23}}},"fnMap":{"0":{"name":"mayorGanancia","decl":{"start":{"line":5,"column":26},"end":{"line":5,"column":39}},"loc":{"start":{"line":5,"column":55},"end":{"line":18,"column":1}},"line":5}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":12},"end":{"line":13,"column":13}},"type":"if","locations":[{"start":{"line":11,"column":12},"end":{"line":13,"column":13}},{"start":{"line":11,"column":12},"end":{"line":13,"column":13}}],"line":11}},"s":{"0":1,"1":2,"2":2,"3":2,"4":8,"5":8,"6":20,"7":20,"8":8,"9":2},"f":{"0":2},"b":{"0":[8,12]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"6f3c18e08027397aacd8a41b21332a52e4564bfe"} 4 | ,"/home/alemendoza/SoyHenry/reactoTesting/problems/minStack.js": {"path":"/home/alemendoza/SoyHenry/reactoTesting/problems/minStack.js","statementMap":{"0":{"start":{"line":16,"column":8},"end":{"line":16,"column":27}},"1":{"start":{"line":17,"column":8},"end":{"line":17,"column":25}},"2":{"start":{"line":23,"column":8},"end":{"line":23,"column":28}},"3":{"start":{"line":27,"column":8},"end":{"line":35,"column":9}},"4":{"start":{"line":28,"column":12},"end":{"line":28,"column":47}},"5":{"start":{"line":32,"column":30},"end":{"line":32,"column":48}},"6":{"start":{"line":33,"column":12},"end":{"line":33,"column":42}},"7":{"start":{"line":34,"column":12},"end":{"line":34,"column":37}},"8":{"start":{"line":39,"column":29},"end":{"line":39,"column":41}},"9":{"start":{"line":40,"column":8},"end":{"line":40,"column":57}},"10":{"start":{"line":41,"column":8},"end":{"line":41,"column":50}},"11":{"start":{"line":45,"column":8},"end":{"line":45,"column":50}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":15,"column":4},"end":{"line":15,"column":5}},"loc":{"start":{"line":15,"column":23},"end":{"line":18,"column":5}},"line":15},"1":{"name":"(anonymous_1)","decl":{"start":{"line":22,"column":4},"end":{"line":22,"column":5}},"loc":{"start":{"line":22,"column":17},"end":{"line":24,"column":5}},"line":22},"2":{"name":"(anonymous_2)","decl":{"start":{"line":26,"column":4},"end":{"line":26,"column":5}},"loc":{"start":{"line":26,"column":19},"end":{"line":36,"column":5}},"line":26},"3":{"name":"(anonymous_3)","decl":{"start":{"line":38,"column":4},"end":{"line":38,"column":5}},"loc":{"start":{"line":38,"column":10},"end":{"line":42,"column":5}},"line":38},"4":{"name":"(anonymous_4)","decl":{"start":{"line":44,"column":4},"end":{"line":44,"column":5}},"loc":{"start":{"line":44,"column":9},"end":{"line":46,"column":5}},"line":44}},"branchMap":{"0":{"loc":{"start":{"line":27,"column":8},"end":{"line":35,"column":9}},"type":"if","locations":[{"start":{"line":27,"column":8},"end":{"line":35,"column":9}},{"start":{"line":27,"column":8},"end":{"line":35,"column":9}}],"line":27},"1":{"loc":{"start":{"line":40,"column":23},"end":{"line":40,"column":56}},"type":"binary-expr","locations":[{"start":{"line":40,"column":23},"end":{"line":40,"column":35}},{"start":{"line":40,"column":39},"end":{"line":40,"column":56}}],"line":40},"2":{"loc":{"start":{"line":41,"column":15},"end":{"line":41,"column":49}},"type":"binary-expr","locations":[{"start":{"line":41,"column":15},"end":{"line":41,"column":27}},{"start":{"line":41,"column":31},"end":{"line":41,"column":49}}],"line":41},"3":{"loc":{"start":{"line":45,"column":15},"end":{"line":45,"column":49}},"type":"binary-expr","locations":[{"start":{"line":45,"column":15},"end":{"line":45,"column":27}},{"start":{"line":45,"column":31},"end":{"line":45,"column":49}}],"line":45}},"s":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0},"f":{"0":0,"1":0,"2":0,"3":0,"4":0},"b":{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"6cd186d45be88a28e7e0383db0468a8d2c907404"} 5 | ,"/home/alemendoza/SoyHenry/reactoTesting/problems/multidimensionalArray.js": {"path":"/home/alemendoza/SoyHenry/reactoTesting/problems/multidimensionalArray.js","statementMap":{"0":{"start":{"line":4,"column":0},"end":{"line":14,"column":3}},"1":{"start":{"line":5,"column":14},"end":{"line":5,"column":15}},"2":{"start":{"line":6,"column":4},"end":{"line":12,"column":5}},"3":{"start":{"line":6,"column":17},"end":{"line":6,"column":18}},"4":{"start":{"line":7,"column":6},"end":{"line":11,"column":7}},"5":{"start":{"line":8,"column":8},"end":{"line":8,"column":40}},"6":{"start":{"line":10,"column":8},"end":{"line":10,"column":29}},"7":{"start":{"line":13,"column":4},"end":{"line":13,"column":15}}},"fnMap":{"0":{"name":"mDSumArray","decl":{"start":{"line":4,"column":26},"end":{"line":4,"column":36}},"loc":{"start":{"line":4,"column":44},"end":{"line":14,"column":3}},"line":4}},"branchMap":{"0":{"loc":{"start":{"line":7,"column":6},"end":{"line":11,"column":7}},"type":"if","locations":[{"start":{"line":7,"column":6},"end":{"line":11,"column":7}},{"start":{"line":7,"column":6},"end":{"line":11,"column":7}}],"line":7}},"s":{"0":1,"1":10,"2":10,"3":10,"4":25,"5":7,"6":18,"7":10},"f":{"0":10},"b":{"0":[7,18]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"2c2fbbb4967fbfb8eee946e6461f76dd0e68837a"} 6 | } 7 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/base.css: -------------------------------------------------------------------------------- 1 | body, html { 2 | margin:0; padding: 0; 3 | height: 100%; 4 | } 5 | body { 6 | font-family: Helvetica Neue, Helvetica, Arial; 7 | font-size: 14px; 8 | color:#333; 9 | } 10 | .small { font-size: 12px; } 11 | *, *:after, *:before { 12 | -webkit-box-sizing:border-box; 13 | -moz-box-sizing:border-box; 14 | box-sizing:border-box; 15 | } 16 | h1 { font-size: 20px; margin: 0;} 17 | h2 { font-size: 14px; } 18 | pre { 19 | font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; 20 | margin: 0; 21 | padding: 0; 22 | -moz-tab-size: 2; 23 | -o-tab-size: 2; 24 | tab-size: 2; 25 | } 26 | a { color:#0074D9; text-decoration:none; } 27 | a:hover { text-decoration:underline; } 28 | .strong { font-weight: bold; } 29 | .space-top1 { padding: 10px 0 0 0; } 30 | .pad2y { padding: 20px 0; } 31 | .pad1y { padding: 10px 0; } 32 | .pad2x { padding: 0 20px; } 33 | .pad2 { padding: 20px; } 34 | .pad1 { padding: 10px; } 35 | .space-left2 { padding-left:55px; } 36 | .space-right2 { padding-right:20px; } 37 | .center { text-align:center; } 38 | .clearfix { display:block; } 39 | .clearfix:after { 40 | content:''; 41 | display:block; 42 | height:0; 43 | clear:both; 44 | visibility:hidden; 45 | } 46 | .fl { float: left; } 47 | @media only screen and (max-width:640px) { 48 | .col3 { width:100%; max-width:100%; } 49 | .hide-mobile { display:none!important; } 50 | } 51 | 52 | .quiet { 53 | color: #7f7f7f; 54 | color: rgba(0,0,0,0.5); 55 | } 56 | .quiet a { opacity: 0.7; } 57 | 58 | .fraction { 59 | font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; 60 | font-size: 10px; 61 | color: #555; 62 | background: #E8E8E8; 63 | padding: 4px 5px; 64 | border-radius: 3px; 65 | vertical-align: middle; 66 | } 67 | 68 | div.path a:link, div.path a:visited { color: #333; } 69 | table.coverage { 70 | border-collapse: collapse; 71 | margin: 10px 0 0 0; 72 | padding: 0; 73 | } 74 | 75 | table.coverage td { 76 | margin: 0; 77 | padding: 0; 78 | vertical-align: top; 79 | } 80 | table.coverage td.line-count { 81 | text-align: right; 82 | padding: 0 5px 0 20px; 83 | } 84 | table.coverage td.line-coverage { 85 | text-align: right; 86 | padding-right: 10px; 87 | min-width:20px; 88 | } 89 | 90 | table.coverage td span.cline-any { 91 | display: inline-block; 92 | padding: 0 5px; 93 | width: 100%; 94 | } 95 | .missing-if-branch { 96 | display: inline-block; 97 | margin-right: 5px; 98 | border-radius: 3px; 99 | position: relative; 100 | padding: 0 4px; 101 | background: #333; 102 | color: yellow; 103 | } 104 | 105 | .skip-if-branch { 106 | display: none; 107 | margin-right: 10px; 108 | position: relative; 109 | padding: 0 4px; 110 | background: #ccc; 111 | color: white; 112 | } 113 | .missing-if-branch .typ, .skip-if-branch .typ { 114 | color: inherit !important; 115 | } 116 | .coverage-summary { 117 | border-collapse: collapse; 118 | width: 100%; 119 | } 120 | .coverage-summary tr { border-bottom: 1px solid #bbb; } 121 | .keyline-all { border: 1px solid #ddd; } 122 | .coverage-summary td, .coverage-summary th { padding: 10px; } 123 | .coverage-summary tbody { border: 1px solid #bbb; } 124 | .coverage-summary td { border-right: 1px solid #bbb; } 125 | .coverage-summary td:last-child { border-right: none; } 126 | .coverage-summary th { 127 | text-align: left; 128 | font-weight: normal; 129 | white-space: nowrap; 130 | } 131 | .coverage-summary th.file { border-right: none !important; } 132 | .coverage-summary th.pct { } 133 | .coverage-summary th.pic, 134 | .coverage-summary th.abs, 135 | .coverage-summary td.pct, 136 | .coverage-summary td.abs { text-align: right; } 137 | .coverage-summary td.file { white-space: nowrap; } 138 | .coverage-summary td.pic { min-width: 120px !important; } 139 | .coverage-summary tfoot td { } 140 | 141 | .coverage-summary .sorter { 142 | height: 10px; 143 | width: 7px; 144 | display: inline-block; 145 | margin-left: 0.5em; 146 | background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; 147 | } 148 | .coverage-summary .sorted .sorter { 149 | background-position: 0 -20px; 150 | } 151 | .coverage-summary .sorted-desc .sorter { 152 | background-position: 0 -10px; 153 | } 154 | .status-line { height: 10px; } 155 | /* yellow */ 156 | .cbranch-no { background: yellow !important; color: #111; } 157 | /* dark red */ 158 | .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } 159 | .low .chart { border:1px solid #C21F39 } 160 | .highlighted, 161 | .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ 162 | background: #C21F39 !important; 163 | } 164 | /* medium red */ 165 | .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } 166 | /* light red */ 167 | .low, .cline-no { background:#FCE1E5 } 168 | /* light green */ 169 | .high, .cline-yes { background:rgb(230,245,208) } 170 | /* medium green */ 171 | .cstat-yes { background:rgb(161,215,106) } 172 | /* dark green */ 173 | .status-line.high, .high .cover-fill { background:rgb(77,146,33) } 174 | .high .chart { border:1px solid rgb(77,146,33) } 175 | /* dark yellow (gold) */ 176 | .status-line.medium, .medium .cover-fill { background: #f9cd0b; } 177 | .medium .chart { border:1px solid #f9cd0b; } 178 | /* light yellow */ 179 | .medium { background: #fff4c2; } 180 | 181 | .cstat-skip { background: #ddd; color: #111; } 182 | .fstat-skip { background: #ddd; color: #111 !important; } 183 | .cbranch-skip { background: #ddd !important; color: #111; } 184 | 185 | span.cline-neutral { background: #eaeaea; } 186 | 187 | .coverage-summary td.empty { 188 | opacity: .5; 189 | padding-top: 4px; 190 | padding-bottom: 4px; 191 | line-height: 1; 192 | color: #888; 193 | } 194 | 195 | .cover-fill, .cover-empty { 196 | display:inline-block; 197 | height: 12px; 198 | } 199 | .chart { 200 | line-height: 0; 201 | } 202 | .cover-empty { 203 | background: white; 204 | } 205 | .cover-full { 206 | border-right: none !important; 207 | } 208 | pre.prettyprint { 209 | border: none !important; 210 | padding: 0 !important; 211 | margin: 0 !important; 212 | } 213 | .com { color: #999 !important; } 214 | .ignore-none { color: #999; font-weight: normal; } 215 | 216 | .wrapper { 217 | min-height: 100%; 218 | height: auto !important; 219 | height: 100%; 220 | margin: 0 auto -48px; 221 | } 222 | .footer, .push { 223 | height: 48px; 224 | } 225 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/block-navigation.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var jumpToCode = (function init() { 3 | // Classes of code we would like to highlight in the file view 4 | var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; 5 | 6 | // Elements to highlight in the file listing view 7 | var fileListingElements = ['td.pct.low']; 8 | 9 | // We don't want to select elements that are direct descendants of another match 10 | var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` 11 | 12 | // Selecter that finds elements on the page to which we can jump 13 | var selector = 14 | fileListingElements.join(', ') + 15 | ', ' + 16 | notSelector + 17 | missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` 18 | 19 | // The NodeList of matching elements 20 | var missingCoverageElements = document.querySelectorAll(selector); 21 | 22 | var currentIndex; 23 | 24 | function toggleClass(index) { 25 | missingCoverageElements 26 | .item(currentIndex) 27 | .classList.remove('highlighted'); 28 | missingCoverageElements.item(index).classList.add('highlighted'); 29 | } 30 | 31 | function makeCurrent(index) { 32 | toggleClass(index); 33 | currentIndex = index; 34 | missingCoverageElements.item(index).scrollIntoView({ 35 | behavior: 'smooth', 36 | block: 'center', 37 | inline: 'center' 38 | }); 39 | } 40 | 41 | function goToPrevious() { 42 | var nextIndex = 0; 43 | if (typeof currentIndex !== 'number' || currentIndex === 0) { 44 | nextIndex = missingCoverageElements.length - 1; 45 | } else if (missingCoverageElements.length > 1) { 46 | nextIndex = currentIndex - 1; 47 | } 48 | 49 | makeCurrent(nextIndex); 50 | } 51 | 52 | function goToNext() { 53 | var nextIndex = 0; 54 | 55 | if ( 56 | typeof currentIndex === 'number' && 57 | currentIndex < missingCoverageElements.length - 1 58 | ) { 59 | nextIndex = currentIndex + 1; 60 | } 61 | 62 | makeCurrent(nextIndex); 63 | } 64 | 65 | return function jump(event) { 66 | switch (event.which) { 67 | case 78: // n 68 | case 74: // j 69 | goToNext(); 70 | break; 71 | case 66: // b 72 | case 75: // k 73 | case 80: // p 74 | goToPrevious(); 75 | break; 76 | } 77 | }; 78 | })(); 79 | window.addEventListener('keydown', jumpToCode); 80 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/bracketValidator.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for bracketValidator.js 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |
21 |

All files bracketValidator.js

22 |
23 | 24 |
25 | 100% 26 | Statements 27 | 11/11 28 |
29 | 30 | 31 |
32 | 100% 33 | Branches 34 | 4/4 35 |
36 | 37 | 38 |
39 | 100% 40 | Functions 41 | 1/1 42 |
43 | 44 | 45 |
46 | 100% 47 | Lines 48 | 10/10 49 |
50 | 51 | 52 |
53 |

54 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 55 |

56 |
57 |
58 |

 59 | 
1 60 | 2 61 | 3 62 | 4 63 | 5 64 | 6 65 | 7 66 | 8 67 | 9 68 | 10 69 | 11 70 | 12 71 | 13 72 | 14 73 | 15 74 | 16 75 | 17 76 | 18 77 | 19 78 | 20 79 | 21 80 | 22 81 | 23 82 | 24 83 | 25 84 | 26 85 | 27 86 | 28  87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 | 1x 95 |   96 | 4x 97 |   98 |   99 |   100 |   101 | 4x 102 | 4x 103 | 27x 104 | 16x 105 |   106 | 11x 107 | 2x 108 |   109 | 9x 110 |   111 | 2x 112 |   113 |  
// Crear un bracket validator,
114 | // que este balanceado correctamente, los brackets validos son los siguientes,
115 |  
116 | // '{[],()}' deberia devolver true
117 | // '{[(])}' deberia devolver false
118 | // '{[(' deberia devolver false
119 | // {[([{()[]{}}])]} deberia devolver true
120 |  
121 | module.exports = function bracketValidator(cadena) {
122 |  
123 |     const bracket = {
124 |         '{': '}',
125 |         '[': ']',
126 |         '(': ')'
127 |     }
128 |     const openBracket = [];
129 |     for (var i = 0; i < cadena.length; i++) {
130 |         if (bracket[cadena[i]]) {
131 |             openBracket.push(cadena[i])
132 |         }
133 |         else if (bracket[openBracket.pop()] !== cadena[i]) {
134 |             return false;
135 |         }
136 |         else continue;
137 |     }
138 |     return !openBracket.length;
139 | }
140 |  
141 | 142 |
143 |
144 | 149 | 150 | 151 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/Ejercicios/Tests/coverage/lcov-report/favicon.png -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for All files 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |
21 |

All files

22 |
23 | 24 |
25 | 76.47% 26 | Statements 27 | 39/51 28 |
29 | 30 | 31 |
32 | 60% 33 | Branches 34 | 12/20 35 |
36 | 37 | 38 |
39 | 44.44% 40 | Functions 41 | 4/9 42 |
43 | 44 | 45 |
46 | 72.09% 47 | Lines 48 | 31/43 49 |
50 | 51 | 52 |
53 |

54 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 55 |

56 |
57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 |
FileStatementsBranchesFunctionsLines
bracketValidator.js 77 |
78 |
100%11/11100%4/4100%1/1100%10/10
indexArray.js 92 |
93 |
100%10/10100%4/4100%1/1100%6/6
mayorGanancia.js 107 |
108 |
100%10/10100%2/2100%1/1100%8/8
minStack.js 122 |
123 |
0%0/120%0/80%0/50%0/12
multidimensionalArray.js 137 |
138 |
100%8/8100%2/2100%1/1100%7/7
151 |
152 |
153 |
154 | 159 | 160 | 161 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/indexArray.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for indexArray.js 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |
21 |

All files indexArray.js

22 |
23 | 24 |
25 | 100% 26 | Statements 27 | 10/10 28 |
29 | 30 | 31 |
32 | 100% 33 | Branches 34 | 4/4 35 |
36 | 37 | 38 |
39 | 100% 40 | Functions 41 | 1/1 42 |
43 | 44 | 45 |
46 | 100% 47 | Lines 48 | 6/6 49 |
50 | 51 | 52 |
53 |

54 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 55 |

56 |
57 |
58 |

 59 | 
1 60 | 2 61 | 3 62 | 4 63 | 5 64 | 6 65 | 7 66 | 8 67 | 9 68 | 10 69 | 11 70 | 12 71 | 13 72 | 14 73 | 15 74 | 16 75 | 17 76 | 18 77 | 19 78 | 20 79 | 21 80 | 22 81 | 23 82 | 24 83 | 25 84 | 26 85 | 27 86 | 28 87 | 29 88 | 30 89 | 31  90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |   99 |   100 |   101 |   102 |   103 | 1x 104 |   105 | 2x 106 |   107 | 18x 108 |   109 |   110 | 24x 111 |   112 | 7x 113 |   114 |   115 |   116 | 1x 117 |   118 |   119 |  
//encontrar el indice de la primera aparicion de un string(needle)
120 | //dentro de otro(haystack)
121 | //no se puede utilizar indexOf()
122 |  
123 | //ejemplo: 
124 | //haystack = 'react-redux'
125 | //needle = 'redux'
126 | //output = 5
127 |  
128 | //haystack = 'react-redux'
129 | //needle = 'hola'
130 | //output = -1
131 |  
132 |  
133 | module.exports =  function findNeedle(haystack, needle) {
134 |     // iteramos sobre el haystack
135 |     for (let haystackIndex = 0; haystackIndex < haystack.length; haystackIndex += 1) {
136 |       // comenzamos a iterar sobre el needle
137 |       for (let needleIndex = 0; needleIndex < needle.length; needleIndex += 1 ) {
138 |         // comparamos la letra del needle en la que estamos con la letra del haystack
139 |           // cuando no hay match cortamos de comparar el needle
140 |         if (haystack[haystackIndex + needleIndex] !== needle[needleIndex]) break;
141 |         // si terminamos de recorrer la needle devolvemos el haystackIndex
142 |         if (needleIndex + 1 === needle.length) return haystackIndex;
143 |       }
144 |     }
145 |     // una vez que termina el loop devolvemos -1
146 |     return -1;
147 |   }
148 |  
149 |  
150 | 151 |
152 |
153 | 158 | 159 | 160 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/mayorGanancia.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for mayorGanancia.js 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |
21 |

All files mayorGanancia.js

22 |
23 | 24 |
25 | 100% 26 | Statements 27 | 10/10 28 |
29 | 30 | 31 |
32 | 100% 33 | Branches 34 | 2/2 35 |
36 | 37 | 38 |
39 | 100% 40 | Functions 41 | 1/1 42 |
43 | 44 | 45 |
46 | 100% 47 | Lines 48 | 8/8 49 |
50 | 51 | 52 |
53 |

54 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 55 |

56 |
57 |
58 |

 59 | 
1 60 | 2 61 | 3 62 | 4 63 | 5 64 | 6 65 | 7 66 | 8 67 | 9 68 | 10 69 | 11 70 | 12 71 | 13 72 | 14 73 | 15 74 | 16 75 | 17 76 | 18  77 |   78 |   79 |   80 | 1x 81 | 2x 82 | 2x 83 | 8x 84 | 20x 85 |   86 | 20x 87 | 8x 88 |   89 |   90 |   91 |   92 | 2x 93 |  
//Dado un arreglo de valores de acciones, 
 94 | //encontrar la mayor ganancia posible de comprar a un horario y vender después. 
 95 | //acciones: [4, 3, 2, 5, 11] mayor ganancia: 9;
 96 |  
 97 | module.exports = function mayorGanancia(arrayAcciones) {
 98 |     let viejoMaximo = arrayAcciones[1] - arrayAcciones[0];
 99 |     for (let i = 0; i < arrayAcciones.length - 1; i += 1) {
100 |         for (let j = i + 1; j < arrayAcciones.length; j += 1) {
101 |             let gananciaPotencial = arrayAcciones[j] - arrayAcciones[i];
102 |             
103 |             if(viejoMaximo < gananciaPotencial){
104 |                 viejoMaximo = gananciaPotencial;
105 |             } 
106 |         }
107 |  
108 |     }
109 |     return viejoMaximo;
110 | }
111 | 112 |
113 |
114 | 119 | 120 | 121 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/minStack.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for minStack.js 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |
21 |

All files minStack.js

22 |
23 | 24 |
25 | 0% 26 | Statements 27 | 0/12 28 |
29 | 30 | 31 |
32 | 0% 33 | Branches 34 | 0/8 35 |
36 | 37 | 38 |
39 | 0% 40 | Functions 41 | 0/5 42 |
43 | 44 | 45 |
46 | 0% 47 | Lines 48 | 0/12 49 |
50 | 51 | 52 |
53 |

54 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 55 |

56 |
57 |
58 |

 59 | 
1 60 | 2 61 | 3 62 | 4 63 | 5 64 | 6 65 | 7 66 | 8 67 | 9 68 | 10 69 | 11 70 | 12 71 | 13 72 | 14 73 | 15 74 | 16 75 | 17 76 | 18 77 | 19 78 | 20 79 | 21 80 | 22 81 | 23 82 | 24 83 | 25 84 | 26 85 | 27 86 | 28 87 | 29 88 | 30 89 | 31 90 | 32 91 | 33 92 | 34 93 | 35 94 | 36 95 | 37 96 | 38 97 | 39 98 | 40 99 | 41 100 | 42 101 | 43 102 | 44 103 | 45 104 | 46 105 | 47 106 | 48 107 | 49 108 | 50  109 |   110 |   111 |   112 |   113 |   114 |   115 |   116 |   117 |   118 |   119 |   120 |   121 |   122 |   123 |   124 |   125 |   126 |   127 |   128 |   129 |   130 |   131 |   132 |   133 |   134 |   135 |   136 |   137 |   138 |   139 |   140 |   141 |   142 |   143 |   144 |   145 |   146 |   147 |   148 |   149 |   150 |   151 |   152 |   153 |   154 |   155 |   156 |   157 |  
// Un stack o Pila es LIFO (last in first out), 
158 | // osea el ultimo que entro es el primeor en salir. 
159 | // Necesitas implementar un stack que tenga los siguientes métodos: 
160 | // - push(value) // para añadir elementos 
161 | // - pop() // para sacar un elemento 
162 | // - min () // ver el elemento con el valor minimo Todas estas funciones tienen que correr en 0(1) 
163 | // No se puede usar ningún array method 
164 | // Idea: Tener una estructura separada para guardar el minimo 
165 | // de cada nodo que se agrega, 
166 | // y cuando sacamos el nodo removemos ese minimo.
167 |  
168 | //dos clases, una con metodos pop,push,min
169 |  
170 | class Node {
171 |     constructor(value) {
172 |         this.valor = value;
173 |         this.next = null;
174 |     }
175 | }
176 |  
177 | class Stack {
178 |     constructor(){
179 |         this.primero = null;
180 |     }
181 |  
182 |     push(elemento) {
183 |         if(!this.primero){
184 |             this.primero = new Node (elemento);
185 |         }
186 |  
187 |         else {
188 |             const nuevoNodo = new Node(elemento);
189 |             nuevoNodo.next = this.primero;
190 |             this.primero = nuevoNodo;
191 |         }
192 |     }
193 |  
194 |     pop() {
195 |         const primeroSalir = this.primero;
196 |         this.primero = primeroSalir && primeroSalir.next;
197 |         return primeroSalir && primeroSalir.valor;
198 |     }
199 |  
200 |     min(){
201 |         return this.primero && this.primero.valor;
202 |     }
203 | }
204 |  
205 |  
206 |  
207 | 208 |
209 |
210 | 215 | 216 | 217 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/multidimensionalArray.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for multidimensionalArray.js 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 |
20 |
21 |

All files multidimensionalArray.js

22 |
23 | 24 |
25 | 100% 26 | Statements 27 | 8/8 28 |
29 | 30 | 31 |
32 | 100% 33 | Branches 34 | 2/2 35 |
36 | 37 | 38 |
39 | 100% 40 | Functions 41 | 1/1 42 |
43 | 44 | 45 |
46 | 100% 47 | Lines 48 | 7/7 49 |
50 | 51 | 52 |
53 |

54 | Press n or j to go to the next uncovered block, b, p or k for the previous block. 55 |

56 |
57 |
58 |

 59 | 
1 60 | 2 61 | 3 62 | 4 63 | 5 64 | 6 65 | 7 66 | 8 67 | 9 68 | 10 69 | 11 70 | 12 71 | 13 72 | 14  73 |   74 |   75 | 1x 76 | 10x 77 | 10x 78 | 25x 79 | 7x 80 |   81 | 18x 82 |   83 |   84 | 10x 85 |  
 
 86 | //tu codigo aqui:
 87 |  
 88 | module.exports = function mDSumArray(array) {
 89 |     var acc = 0;
 90 |     for (let i = 0; i < array.length; i++) {
 91 |       if (Array.isArray(array[i])) {
 92 |         acc = acc + mDSumArray(array[i])
 93 |       } else {
 94 |         acc = acc + array[i];
 95 |       }
 96 |     }
 97 |     return acc;
 98 |   }
99 | 100 |
101 |
102 | 107 | 108 | 109 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} 2 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/prettify.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/Ejercicios/Tests/coverage/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov-report/sorter.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var addSorting = (function() { 3 | 'use strict'; 4 | var cols, 5 | currentSort = { 6 | index: 0, 7 | desc: false 8 | }; 9 | 10 | // returns the summary table element 11 | function getTable() { 12 | return document.querySelector('.coverage-summary'); 13 | } 14 | // returns the thead element of the summary table 15 | function getTableHeader() { 16 | return getTable().querySelector('thead tr'); 17 | } 18 | // returns the tbody element of the summary table 19 | function getTableBody() { 20 | return getTable().querySelector('tbody'); 21 | } 22 | // returns the th element for nth column 23 | function getNthColumn(n) { 24 | return getTableHeader().querySelectorAll('th')[n]; 25 | } 26 | 27 | // loads all columns 28 | function loadColumns() { 29 | var colNodes = getTableHeader().querySelectorAll('th'), 30 | colNode, 31 | cols = [], 32 | col, 33 | i; 34 | 35 | for (i = 0; i < colNodes.length; i += 1) { 36 | colNode = colNodes[i]; 37 | col = { 38 | key: colNode.getAttribute('data-col'), 39 | sortable: !colNode.getAttribute('data-nosort'), 40 | type: colNode.getAttribute('data-type') || 'string' 41 | }; 42 | cols.push(col); 43 | if (col.sortable) { 44 | col.defaultDescSort = col.type === 'number'; 45 | colNode.innerHTML = 46 | colNode.innerHTML + ''; 47 | } 48 | } 49 | return cols; 50 | } 51 | // attaches a data attribute to every tr element with an object 52 | // of data values keyed by column name 53 | function loadRowData(tableRow) { 54 | var tableCols = tableRow.querySelectorAll('td'), 55 | colNode, 56 | col, 57 | data = {}, 58 | i, 59 | val; 60 | for (i = 0; i < tableCols.length; i += 1) { 61 | colNode = tableCols[i]; 62 | col = cols[i]; 63 | val = colNode.getAttribute('data-value'); 64 | if (col.type === 'number') { 65 | val = Number(val); 66 | } 67 | data[col.key] = val; 68 | } 69 | return data; 70 | } 71 | // loads all row data 72 | function loadData() { 73 | var rows = getTableBody().querySelectorAll('tr'), 74 | i; 75 | 76 | for (i = 0; i < rows.length; i += 1) { 77 | rows[i].data = loadRowData(rows[i]); 78 | } 79 | } 80 | // sorts the table using the data for the ith column 81 | function sortByIndex(index, desc) { 82 | var key = cols[index].key, 83 | sorter = function(a, b) { 84 | a = a.data[key]; 85 | b = b.data[key]; 86 | return a < b ? -1 : a > b ? 1 : 0; 87 | }, 88 | finalSorter = sorter, 89 | tableBody = document.querySelector('.coverage-summary tbody'), 90 | rowNodes = tableBody.querySelectorAll('tr'), 91 | rows = [], 92 | i; 93 | 94 | if (desc) { 95 | finalSorter = function(a, b) { 96 | return -1 * sorter(a, b); 97 | }; 98 | } 99 | 100 | for (i = 0; i < rowNodes.length; i += 1) { 101 | rows.push(rowNodes[i]); 102 | tableBody.removeChild(rowNodes[i]); 103 | } 104 | 105 | rows.sort(finalSorter); 106 | 107 | for (i = 0; i < rows.length; i += 1) { 108 | tableBody.appendChild(rows[i]); 109 | } 110 | } 111 | // removes sort indicators for current column being sorted 112 | function removeSortIndicators() { 113 | var col = getNthColumn(currentSort.index), 114 | cls = col.className; 115 | 116 | cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); 117 | col.className = cls; 118 | } 119 | // adds sort indicators for current column being sorted 120 | function addSortIndicators() { 121 | getNthColumn(currentSort.index).className += currentSort.desc 122 | ? ' sorted-desc' 123 | : ' sorted'; 124 | } 125 | // adds event listeners for all sorter widgets 126 | function enableUI() { 127 | var i, 128 | el, 129 | ithSorter = function ithSorter(i) { 130 | var col = cols[i]; 131 | 132 | return function() { 133 | var desc = col.defaultDescSort; 134 | 135 | if (currentSort.index === i) { 136 | desc = !currentSort.desc; 137 | } 138 | sortByIndex(i, desc); 139 | removeSortIndicators(); 140 | currentSort.index = i; 141 | currentSort.desc = desc; 142 | addSortIndicators(); 143 | }; 144 | }; 145 | for (i = 0; i < cols.length; i += 1) { 146 | if (cols[i].sortable) { 147 | // add the click event handler on the th so users 148 | // dont have to click on those tiny arrows 149 | el = getNthColumn(i).querySelector('.sorter').parentElement; 150 | if (el.addEventListener) { 151 | el.addEventListener('click', ithSorter(i)); 152 | } else { 153 | el.attachEvent('onclick', ithSorter(i)); 154 | } 155 | } 156 | } 157 | } 158 | // adds sorting functionality to the UI 159 | return function() { 160 | if (!getTable()) { 161 | return; 162 | } 163 | cols = loadColumns(); 164 | loadData(); 165 | addSortIndicators(); 166 | enableUI(); 167 | }; 168 | })(); 169 | 170 | window.addEventListener('load', addSorting); 171 | -------------------------------------------------------------------------------- /Ejercicios/Tests/coverage/lcov.info: -------------------------------------------------------------------------------- 1 | TN: 2 | SF:/home/alemendoza/SoyHenry/reactoTesting/problems/bracketValidator.js 3 | FN:9,bracketValidator 4 | FNF:1 5 | FNH:1 6 | FNDA:4,bracketValidator 7 | DA:9,1 8 | DA:11,4 9 | DA:16,4 10 | DA:17,4 11 | DA:18,27 12 | DA:19,16 13 | DA:21,11 14 | DA:22,2 15 | DA:24,9 16 | DA:26,2 17 | LF:10 18 | LH:10 19 | BRDA:18,0,0,16 20 | BRDA:18,0,1,11 21 | BRDA:21,1,0,2 22 | BRDA:21,1,1,9 23 | BRF:4 24 | BRH:4 25 | end_of_record 26 | TN: 27 | SF:/home/alemendoza/SoyHenry/reactoTesting/problems/indexArray.js 28 | FN:15,findNeedle 29 | FNF:1 30 | FNH:1 31 | FNDA:2,findNeedle 32 | DA:15,1 33 | DA:17,2 34 | DA:19,18 35 | DA:22,24 36 | DA:24,7 37 | DA:28,1 38 | LF:6 39 | LH:6 40 | BRDA:22,0,0,17 41 | BRDA:22,0,1,7 42 | BRDA:24,1,0,1 43 | BRDA:24,1,1,6 44 | BRF:4 45 | BRH:4 46 | end_of_record 47 | TN: 48 | SF:/home/alemendoza/SoyHenry/reactoTesting/problems/mayorGanancia.js 49 | FN:5,mayorGanancia 50 | FNF:1 51 | FNH:1 52 | FNDA:2,mayorGanancia 53 | DA:5,1 54 | DA:6,2 55 | DA:7,2 56 | DA:8,8 57 | DA:9,20 58 | DA:11,20 59 | DA:12,8 60 | DA:17,2 61 | LF:8 62 | LH:8 63 | BRDA:11,0,0,8 64 | BRDA:11,0,1,12 65 | BRF:2 66 | BRH:2 67 | end_of_record 68 | TN: 69 | SF:/home/alemendoza/SoyHenry/reactoTesting/problems/minStack.js 70 | FN:15,(anonymous_0) 71 | FN:22,(anonymous_1) 72 | FN:26,(anonymous_2) 73 | FN:38,(anonymous_3) 74 | FN:44,(anonymous_4) 75 | FNF:5 76 | FNH:0 77 | FNDA:0,(anonymous_0) 78 | FNDA:0,(anonymous_1) 79 | FNDA:0,(anonymous_2) 80 | FNDA:0,(anonymous_3) 81 | FNDA:0,(anonymous_4) 82 | DA:16,0 83 | DA:17,0 84 | DA:23,0 85 | DA:27,0 86 | DA:28,0 87 | DA:32,0 88 | DA:33,0 89 | DA:34,0 90 | DA:39,0 91 | DA:40,0 92 | DA:41,0 93 | DA:45,0 94 | LF:12 95 | LH:0 96 | BRDA:27,0,0,0 97 | BRDA:27,0,1,0 98 | BRDA:40,1,0,0 99 | BRDA:40,1,1,0 100 | BRDA:41,2,0,0 101 | BRDA:41,2,1,0 102 | BRDA:45,3,0,0 103 | BRDA:45,3,1,0 104 | BRF:8 105 | BRH:0 106 | end_of_record 107 | TN: 108 | SF:/home/alemendoza/SoyHenry/reactoTesting/problems/multidimensionalArray.js 109 | FN:4,mDSumArray 110 | FNF:1 111 | FNH:1 112 | FNDA:10,mDSumArray 113 | DA:4,1 114 | DA:5,10 115 | DA:6,10 116 | DA:7,25 117 | DA:8,7 118 | DA:10,18 119 | DA:13,10 120 | LF:7 121 | LH:7 122 | BRDA:7,0,0,7 123 | BRDA:7,0,1,18 124 | BRF:2 125 | BRH:2 126 | end_of_record 127 | -------------------------------------------------------------------------------- /Ejercicios/Tests/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: [ 3 | "js", 4 | ], 5 | coverageDirectory: 'coverage', 6 | 7 | }; 8 | -------------------------------------------------------------------------------- /Ejercicios/Tests/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "henrytech", 3 | "version": "1.0.0", 4 | "description": "testing", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --collectCoverage=false" 8 | }, 9 | "homepage": "https://github.com/soyHenry/Entrevistas-Tecnicas#readme", 10 | "dependencies": { 11 | "chai": "^4.2.0", 12 | "jest": "^24.9.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/binarioaDecimal.js: -------------------------------------------------------------------------------- 1 | module.exports = function BinarioADecimal(num) { 2 | 3 | var decimal = num.toString(10); 4 | for(var i = 0; i > decimal.length; i++){ 5 | 6 | if(decimal.charAt(i) != "0" && decimal.charAt(i) != "1") 7 | return false; 8 | 9 | } 10 | var bin = decimal; 11 | var dec = 0; 12 | var binl = bin.length; 13 | var p = 0; 14 | var n = 0; 15 | while(binl > 0) { 16 | p = bin.length - binl; 17 | binl--; 18 | n = parseInt(bin.substr(binl, 1)); 19 | dec += n * Math.pow(2, p); 20 | } 21 | return Number(dec) 22 | 23 | } -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/bracketValidator.js: -------------------------------------------------------------------------------- 1 | // Crear un bracket validator, 2 | // que este balanceado correctamente, los brackets validos son los siguientes, 3 | 4 | // '{[],()}' deberia devolver true 5 | // '{[(])}' deberia devolver false 6 | // '{[(' deberia devolver false 7 | // {[([{()[]{}}])]} deberia devolver true 8 | 9 | module.exports = function bracketValidator(cadena) { 10 | 11 | const bracket = { 12 | '{': '}', 13 | '[': ']', 14 | '(': ')' 15 | } 16 | const openBracket = []; 17 | for (var i = 0; i < cadena.length; i++) { 18 | if (bracket[cadena[i]]) { 19 | openBracket.push(cadena[i]) 20 | } 21 | else if (bracket[openBracket.pop()] !== cadena[i]) { 22 | return false; 23 | } 24 | else continue; 25 | } 26 | return !openBracket.length; 27 | } 28 | -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/decimalABinario.js: -------------------------------------------------------------------------------- 1 | module.exports = function DecimalABinario(num) { 2 | var resultado = num.toString(2) 3 | return resultado; 4 | } 5 | -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/indexArray.js: -------------------------------------------------------------------------------- 1 | //encontrar el indice de la primera aparicion de un string(needle) 2 | //dentro de otro(haystack) 3 | //no se puede utilizar indexOf() 4 | 5 | //ejemplo: 6 | //haystack = 'react-redux' 7 | //needle = 'redux' 8 | //output = 5 9 | 10 | //haystack = 'react-redux' 11 | //needle = 'hola' 12 | //output = -1 13 | 14 | 15 | module.exports = function findNeedle(haystack, needle) { 16 | for (let haystackIndex = 0; haystackIndex < haystack.length; haystackIndex += 1) { 17 | for (let needleIndex = 0; needleIndex < needle.length; needleIndex += 1 ) { 18 | if (haystack[haystackIndex + needleIndex] !== needle[needleIndex]) break; 19 | if (needleIndex + 1 === needle.length) return haystackIndex; 20 | } 21 | } 22 | return -1; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/maxValue: -------------------------------------------------------------------------------- 1 | //Dado un arreglo de valores de acciones, 2 | //encontrar la mayor ganancia posible de comprar a un horario y vender después. 3 | //acciones: [4, 3, 2, 5, 11] mayor ganancia: 9; 4 | 5 | function mayorGanancia(arrayAcciones) { 6 | let viejoMaximo = arrayAcciones[1] - arrayAcciones[0]; 7 | for (i = 0; i < arrayAcciones.length; i++) { 8 | for (j = 1; i < arrayAcciones.length; i++) { 9 | let gananciaPotencial = arrayAcciones[i] - arrayAcciones[j]; 10 | 11 | if(viejoMaximo < gananciaPotencial){ 12 | viejoMaximo = gananciaPotencial; 13 | } 14 | } 15 | 16 | } 17 | return viejoMaximo; 18 | } 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/mayorGanancia.js: -------------------------------------------------------------------------------- 1 | //Dado un arreglo de valores de acciones, 2 | //encontrar la mayor ganancia posible de comprar a un horario y vender después. 3 | //acciones: [4, 3, 2, 5, 11] mayor ganancia: 9; 4 | 5 | module.exports = function mayorGanancia(arrayAcciones) { 6 | let viejoMaximo = arrayAcciones[1] - arrayAcciones[0]; 7 | for (let i = 0; i < arrayAcciones.length - 1; i += 1) { 8 | for (let j = i + 1; j < arrayAcciones.length; j += 1) { 9 | let gananciaPotencial = arrayAcciones[j] - arrayAcciones[i]; 10 | 11 | if(viejoMaximo < gananciaPotencial){ 12 | viejoMaximo = gananciaPotencial; 13 | } 14 | } 15 | 16 | } 17 | return viejoMaximo; 18 | } -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/minStack.js: -------------------------------------------------------------------------------- 1 | // Un stack o Pila es LIFO (last in first out), 2 | // osea el ultimo que entro es el primeor en salir. 3 | // Necesitas implementar un stack que tenga los siguientes métodos: 4 | // - push(value) // para añadir elementos 5 | // - pop() // para sacar un elemento 6 | // - min () // ver el elemento con el valor minimo Todas estas funciones tienen que correr en 0(1) 7 | // No se puede usar ningún array method 8 | // Idea: Tener una estructura separada para guardar el minimo 9 | // de cada nodo que se agrega, 10 | // y cuando sacamos el nodo removemos ese minimo. 11 | 12 | //dos clases, una con metodos pop,push,min 13 | 14 | class Node { 15 | constructor(value) { 16 | this.valor = value; 17 | this.next = null; 18 | } 19 | } 20 | 21 | class Stack { 22 | constructor(){ 23 | this.primero = null; 24 | } 25 | 26 | push(elemento) { 27 | if(!this.primero){ 28 | this.primero = new Node (elemento); 29 | } 30 | 31 | else { 32 | const nuevoNodo = new Node(elemento); 33 | nuevoNodo.next = this.primero; 34 | this.primero = nuevoNodo; 35 | } 36 | } 37 | 38 | pop() { 39 | const primeroSalir = this.primero; 40 | this.primero = primeroSalir && primeroSalir.next; 41 | return primeroSalir && primeroSalir.valor; 42 | } 43 | 44 | min(){ 45 | return this.primero && this.primero.valor; 46 | } 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/multidimensionalArray.js: -------------------------------------------------------------------------------- 1 | 2 | //tu codigo aqui: 3 | 4 | module.exports = function mDSumArray(array) { 5 | var acc = 0; 6 | for (let i = 0; i < array.length; i++) { 7 | if (Array.isArray(array[i])) { 8 | acc = acc + mDSumArray(array[i]) 9 | } else { 10 | acc = acc + array[i]; 11 | } 12 | } 13 | return acc; 14 | } -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/nCapicua.js: -------------------------------------------------------------------------------- 1 | function esPolindromo(num) { 2 | const string = num.toString(); 3 | const newArray = string.split("").reverse().join('') 4 | 5 | if (newArray === string) { 6 | return true 7 | } else { 8 | return false 9 | } 10 | 11 | } 12 | function siguientePolindromo(num) { 13 | while (true) { 14 | 15 | if (esCapicua(num)) { 16 | 17 | return num; 18 | } else { 19 | 20 | num = num + 1; 21 | 22 | } 23 | 24 | } 25 | 26 | 27 | } 28 | module.exports = { 29 | 30 | esPolindromo, 31 | siguientePolindromo 32 | 33 | } -------------------------------------------------------------------------------- /Ejercicios/Tests/problems/stackOcurrencia.js: -------------------------------------------------------------------------------- 1 | function stack(haystack, needle) { 2 | for (let i = 0; i < haystack.length; i += 1) { 3 | for (let j = 0; j < needle.length; j += 1 ) { 4 | if (haystack[i + j] !== needle[j]) break; 5 | if (j + 1 === needle.length) return i; 6 | } 7 | } 8 | return -1; 9 | } 10 | 11 | 12 | function numeroOcurrencia(s0, s1){ 13 | const contador = 0; 14 | while (true){ 15 | let index = needleInstack(s0,s1); 16 | if (index === -1){ 17 | return contador; 18 | }else{ 19 | contador = contador + 1; 20 | s0 = s0.slice(index + 1) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Ejercicios/Tests/test/01-FindNeedle.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const indexArray = require("../01-Ejercicios/FindNeedle"); 3 | 4 | describe("indexArray", function () { 5 | it("encuentra el indice de un array en otro array", function () { 6 | const inicio = indexArray("react-redux", "redux"); 7 | expect(inicio).to.equal(6); 8 | }); 9 | it("si no encuenta needle dentro de haystack", function () { 10 | const retornar = indexArray("react-redux", "hola"); 11 | expect(retornar).to.equal(-1); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/02-SumArray.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const Sumarray = require("../Ejercicios/02-SumArray/SumArray"); 3 | 4 | describe("Sumarray(arr, n)", function () { 5 | it("debe retornar true", function () { 6 | expect(Sumarray([2, 4, 5, 1, 3, 9, 12], 8)).toBe(true); 7 | }); 8 | it("debe retornar false", function () { 9 | expect(Sumarray([2, 4, 5, 1, 3, 9, 12], 8)).toBe(false); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/03-MaxValue.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const mayorGanancia = require("../03-Ejercicios/MaxValue"); 3 | 4 | describe("mayorGanancia", function () { 5 | it("debe retornar la mayor ganancia", function () { 6 | let mayor = mayorGanancia([4, 3, 2, 5, 11]); 7 | expect(mayor).to.equal(9); 8 | }); 9 | it("debe poder recibir y sacar la mayor ganancia", function () { 10 | let mayor = mayorGanancia([7, "3", 4, 8, 6]); 11 | expect(mayor).to.equal(5); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/04-multidimensionalArray.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const multidimensionalArray = require("../04-Ejercicios/MultidimensionalSumArray"); 3 | 4 | describe("multidimensionalArray", function () { 5 | it("describe la funcion para encontrar la suma de cada elemento del arreglo", function () { 6 | let resultado = multidimensionalArray([1, 2, 3, 4]); 7 | expect(resultado).to.equal(10); 8 | }); 9 | it("suma de array con subArray", function () { 10 | let resultado = multidimensionalArray([[2, 4], [1], [4, 2, 1]]); 11 | expect(resultado).to.equal(14); 12 | }); 13 | it("suma de array con otro sub array, dentro de un sub array", function () { 14 | let resultado = multidimensionalArray([2, [3, 4], 5, [-3, [6, [4, 5]]]]); 15 | expect(resultado).to.equal(26); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/05-minStack.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const minStack = require("../05-Ejercicios/MinStack"); 3 | 4 | describe("minStack", function () { 5 | it("Chequeamos la clase constructora", () => { 6 | const minStack = new MinStack(); 7 | expect(minStack).toHaveBeenCalledTimes(new Node()); 8 | }); 9 | it("pushes, pops, and peaks", () => { 10 | const minStack = new MinStack(); 11 | 12 | minStack.push(4); 13 | minStack.push(1); 14 | minStack.push(1000); 15 | 16 | Test.assertEquals(minStack.peak(), 1000, "peak fails"); 17 | Test.assertEquals(minStack.pop(), 1000, "pop fails"); 18 | Test.assertEquals(minStack.peak(), 1, "peak fails"); 19 | Test.assertEquals(minStack.pop(), 1, "pop fails"); 20 | Test.assertEquals(minStack.peak(), 4, "peak fails"); 21 | Test.assertEquals(minStack.pop(), 4, "pop fails"); 22 | }); 23 | 24 | it("mins!", () => { 25 | const minStack = new MinStack(); 26 | 27 | minStack.push(4); 28 | minStack.push(1); 29 | minStack.push(1000); 30 | minStack.push(0.5); 31 | minStack.push(5000); 32 | minStack.push(0.1); 33 | 34 | Test.assertEquals(minStack.min(), 0.1, "min fails"); 35 | minStack.pop(); 36 | Test.assertEquals(minStack.min(), 0.5, "min fails"); 37 | minStack.pop(); 38 | Test.assertEquals(minStack.min(), 0.5, "min fails"); 39 | minStack.pop(); 40 | Test.assertEquals(minStack.min(), 1, "min fails"); 41 | minStack.pop(); 42 | Test.assertEquals(minStack.min(), 1, "min fails"); 43 | minStack.pop(); 44 | Test.assertEquals(minStack.min(), 4, "min fails"); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/06-HasBalancedBrackets.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const validatorBracket = require("../06-Ejercicios/HasBalanceBrackets"); 3 | 4 | describe("validatorBacket", function () { 5 | it("", function () { 6 | const resultado = validatorBracket("{[],()}"); 7 | expect(resultado).to.equal(true); 8 | }); 9 | it("", function () { 10 | const resultado = validatorBracket("{[(])}"); 11 | expect(resultado).to.equal(false); 12 | }); 13 | it("", function () { 14 | const resultado = validatorBracket("{[("); 15 | expect(resultado).to.equal(false); 16 | }); 17 | it("", function () { 18 | const resultado = validatorBracket("{[([{()[]{}}])]}"); 19 | expect(resultado).to.equal(true); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/07-SolveGraph.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const solveGraph = require("../07-Ejercicios/SolveGraph"); 3 | const graph = { 4 | a: ["c"], 5 | b: ["c"], 6 | c: ["s", "r"], 7 | d: ["a"], 8 | s: ["a", "c"], 9 | r: ["d"], 10 | z: ["z"], 11 | }; 12 | 13 | describe("SolveGraph", function () { 14 | it("debe retornar si los vertices estan unidos", function () { 15 | let flag = solveGraph(graph, "a", "r"); 16 | expect(flag).to.equal(true); 17 | }); 18 | it("debe retornar si los vertices estan unidos", function () { 19 | let flag = solveGraph(graph, "s", "b"); 20 | expect(flag).to.equal(false); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/08-FindWordStartingWith.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const findWSW = require("../Ejercicios/08-FindWordStartingWith"); 3 | const book = { 4 | id: 1, 5 | text: 6 | "Erase una vez un libro de palabras que era un poco aburrido pero tenia mucho", 7 | }; 8 | 9 | describe("minStack", function () { 10 | it("Encontrar las palabras que empiecen con", () => { 11 | const finder = findWSW(book, "de"); 12 | expect(finder).to.equal([23, 112]); 13 | }); 14 | it("Encontrar las palabras que empiecen con", () => { 15 | const finder = findWSW(book, "un"); 16 | expect(finder).to.equal([6, 14, 43, 99, 115]); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/09-binaryToDecimal.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const BinarioADecimal = require("../Ejercicios/09-binaryToDecimal/BinaryToDecimal.js"); 3 | 4 | describe("BinarioaDecimal(num)", function () { 5 | it("debe retornar 2", function () { 6 | expect(BinarioADecimal("10")).toBe(2); 7 | }); 8 | it("debe retornar 7", function () { 9 | expect(BinarioADecimal("111")).toBe(7); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/10-DecimalToBinary.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const DecimalABinario = require("../problems/DecimalaBinario.js"); 3 | 4 | describe("DecimalABinario(num)", function () { 5 | it('should return "100"', function () { 6 | expect(DecimalABinario(4)).toBe("100"); 7 | }); 8 | it('should return "111"', function () { 9 | expect(DecimalABinario(7)).toBe("111"); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/11-ClockMinuteAdder.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const cMA = require("../11-CloclMinuteAdder/ClockMinuteAdder"); 3 | describe("Sumando minutos", function () { 4 | it("Poniendo en hora el reloj", () => { 5 | const cMA = clockMinuteAdder("09:00", 20); 6 | expect(cMA).toBe("09:20"); 7 | const cMA = clockMinuteAdder("01:30", 30); 8 | expect(cMA).toBe("02:00"); 9 | const cMA = clockMinuteAdder("12:45", 100); 10 | expect(cMA).toBe("01:45"); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/12-InterSection.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const interSect = require("../12-InterSection/InterSection"); 3 | 4 | describe("multidimensionalArray", function () { 5 | it("Elementos comunes", function () { 6 | let resultado = interSect([1, 3, 5, 7, 10], [2, 3, 6, 8, 10, 20]); 7 | expect(resultado).to.equal([3, 10]); 8 | let resultado = interSect([1, 9, 5, 7, 11], [2, 3, 6, 8, 10, 20]); 9 | expect(resultado).to.equal([]); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/13-SubSetSum.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const subSetSum = require("../13-SubSetSum/SubSetSum"); 3 | 4 | describe("multidimensionalArray", function () { 5 | it("Suma subconjunto", function () { 6 | let resultado = subSetSum(9, [1, 10, 5, 3]); 7 | expect(resultado).toBe(true); 8 | let resultado = subSetSum(19, [1, 10, 5, 3]); 9 | expect(resultado).to.toBe(true); 10 | let resultado = subSetSum(17, [1, 10, 5, 3]); 11 | expect(resultado).to.toBe(false); 12 | let resultado = subSetSum(2, [1, 10, 5, 3]); 13 | expect(resultado).to.toBe(false); 14 | let resultado = subSetSum(10, [1, 10, 5, 3]); 15 | expect(resultado).to.toBe(true); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/14-SpyOn.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const spy = require("../Ejercicios/14-SpyOn/SpyOn"); 3 | const adder = (n1, n2) => { 4 | return n1 + n2; 5 | }; 6 | const adderSpy = spy(adder); 7 | 8 | describe("¿Es espia o no?", function () { 9 | it("debe retornar true", function () { 10 | expect(adderSpy.wasCalledWith(2)).toBe(true); 11 | }); 12 | it("debe retornar true", function () { 13 | expect(adderSpy.returned(6)).toBe(true); 14 | }); 15 | it("debe retornar false", function () { 16 | expect(adderSpy.wasCalledWith(0)).toBe(false); 17 | }); 18 | it("debe retornar false", function () { 19 | expect(adderSpy.returned(9)).toBe(false); 20 | }); 21 | it("debe retornar un numero", function () { 22 | expect(adderSpy.getCallCount()).to.equal(0); 23 | }); 24 | it("debe retornar un numero", function () { 25 | expect(adderSpy(2, 4)).to.equal(6); 26 | }); 27 | it("debe retornar un numero", function () { 28 | expect(adderSpy.getCallCount()).to.equal(1); 29 | }); 30 | it("debe retornar un numero", function () { 31 | expect(adderSpy(3, 5)).to.equal(8); 32 | }); 33 | it("debe retornar un numero", function () { 34 | expect(adderSpy.getCallCount()).to.equal(2); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /Ejercicios/Tests/test/15-Curry.spec.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const curry = require("../Ejercicios/15-Curry/Curry"); 3 | const calcAllFour = (var1, var2, var3, var4) => { 4 | return var1 + var2 - var3 * var4; 5 | }; 6 | const curriedDoSomething = curry(calcAllFour); //argumentos -> [] 7 | const firstReturn = curriedDoSomething(1); // argumentos -> [1] 8 | const secondReturn = firstReturn(2); // argumentos -> [1, 2] 9 | const thirdReturn = secondReturn(3); // argumentos -> [1, 2, 3] 10 | const fourthReturn = thirdReturn(4); // -9 -> (1 + 2 - 3 * 4) 11 | 12 | describe("Curring", function () { 13 | it("debe retornar argumentos", function () { 14 | expect(curriedDoSomething).to.equal([]); 15 | expect(firstReturn).to.equal([1]); 16 | expect(secondReturn).to.equal([1, 2]); 17 | expect(thirdReturn).to.equal([1, 2, 3]); 18 | expect(fourthReturn).to.equal(-9); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /Plantillas.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Nombre ejercicio

4 | 5 |
6 |

Encontrar el indice de la primera apariciónde un string (needle) dentro de otro(haystack)

7 |
8 | 9 | 10 |

11 | needle: redux haystack: react-redux output: 5 12 |

13 |

14 | needle: puntualhaystack: pinkyoutput: -1 15 |

16 |
17 | 18 |

no se puede usar indexOf()

19 |
20 |
21 |
22 |
23 |
24 |
25 |

Solucion Humana

26 | 27 | - Visitar cada caracter del haystack 28 | - Si empieza con el primer 29 | - Comparar el segundo caracter del needle con elsiguiente del haystack 30 | - continuar hasta llegar al final del needle o hastaque una comparación no sea igual 31 | - Si llegamos al final del needle es qencontramos el indice 32 | - Si no empieza con el mismo caracter q la needleseguir al proximo caracter 33 | - Si llegamos al final del haystack no encontramos elmatch 34 | 35 |
36 |

 37 | const findNeedle = (haystack, needle) => {
 38 |     // iteramos sobre el haystackfor 
 39 |     (let haystackIndex = 0; haystackIndex < haystack.length; haystackIndex += 1) {
 40 |         // comenzamos a iterar sobre el needle
 41 |         for (let needleIndex = 0; needleIndex < needle.length; needleIndex += 1 ) {
 42 |             // comparamos la letra del needle en la que estamos con la letra del haystack
 43 |             // cuando no hay match cortamos de comparar el needle
 44 |             if (haystack[haystackIndex + needleIndex] !== needle[needleIndex]) break;
 45 |             // si terminamos de recorrer la needle devolvemos el haystackIndex
 46 |             if (needleIndex + 1 === needle.length) return haystackIndex;
 47 |         } 
 48 |     }
 49 |                  // una vez que termina el loop devolvemos -1
 50 |                  return-1;
 51 | }
 52 | 
53 | 54 |
55 |
56 | Complejidad de tiempo 57 |

???

58 |
59 |
60 | Complejidad de espacio 61 |

???

62 |
63 |
64 |
65 |
66 |

Solucion

67 |

 68 | const findNeedle = (haystack, needle) => {
 69 |     // iteramos sobre el haystack
 70 |     for (let haystackIndex = 0; haystackIndex < haystack.length; haystackIndex += 1) {
 71 |         // comenzamos a iterar sobre el needle
 72 |         for (let needleIndex = 0; needleIndex < needle.length; needleIndex += 1 ) {
 73 |             // comparamos la letra del needle en la que estamos con la letra del haystack
 74 |             // cuando no hay match cortamos de comparar el needle
 75 |             if (haystack[haystackIndex + needleIndex] !== needle[needleIndex]) break;
 76 |             // si terminamos de recorrer la needle devolvemos el haystackIndex
 77 |             if (needleIndex + 1 === needle.length) return haystackIndex;
 78 |         }  
 79 |     }
 80 |     // una vez que termina el loop devolvemos -1
 81 |     return-1;
 82 | }
 83 | 
84 | 85 |
86 |
87 | Complejidad de tiempo 88 |

O(n*m)

89 |
90 |
91 | Complejidad de espacio 92 |

0(1)

93 |
94 |
95 | 96 |
97 |
98 |

Solucion

99 |

100 | const findNeedle = (haystack, needle) => {
101 |     // iteramos sobre el haystack
102 |     for (let haystackIndex = 0; haystackIndex < haystack.length; haystackIndex += 1) {
103 |         // comenzamos a iterar sobre el needle
104 |         for (let needleIndex = 0; needleIndex < needle.length; needleIndex += 1 ) {
105 |             // comparamos la letra del needle en la que estamos con la letra del haystack
106 |             // cuando no hay match cortamos de comparar el needle
107 |             if (haystack[haystackIndex + needleIndex] !== needle[needleIndex]) break;
108 |             // si terminamos de recorrer la needle devolvemos el haystackIndex
109 |             if (needleIndex + 1 === needle.length) return haystackIndex;
110 |         }
111 |     }
112 |     // una vez que termina el loop devolvemos -1
113 |     return-1;
114 | }
115 | 
116 | 117 |
118 |
119 | Complejidad de tiempo 120 |

O(n*m)

121 |
122 |
123 | Complejidad de espacio 124 |

0(1)

125 |
126 |
127 | 128 |
129 |
130 |

Solucion Alternativa

131 |

132 | function findNeedle2(haystack, needle){
133 |     // iterar sobre el haystack
134 |     for (let i = 0; i < haystack.length; i += 1) {
135 |         // si la substring matchea el neddle podemos devoler el valor de i
136 |         if (haystack.slice(i, i + needle.length) === needle) {
137 |             return i;      
138 |         }  
139 |     }
140 |     return-1;
141 | }
142 | 
143 | 144 |
145 |
146 | Complejidad de tiempo 147 |

???

148 |
149 |
150 | Complejidad de espacio 151 |

???

152 |
153 |
154 | 155 |
156 |
157 |

Solucion Alternativa

158 |

159 | function findNeedle2(haystack, needle){
160 |     // iterar sobre el haystack
161 |     for (let i = 0; i < haystack.length; i += 1) {
162 |         // si la substring matchea el neddle podemos devoler el valor de i
163 |         if (haystack.slice(i, i + needle.length) === needle) {
164 |             return i;
165 |         }
166 |     }
167 |     return-1;
168 | }
169 | 
170 | 171 |
172 |
173 | Complejidad de tiempo 174 |

???

175 |
176 |
177 | Complejidad de espacio 178 |

???

179 |
180 |
181 |
182 |

Soluciones en

183 | repl.it 184 | 185 | 186 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

Entrevistas Técnicas

3 | 4 |
5 |
6 |

Te preparamos para ingresar al mundo laboral brindándote las herramientas necesarias para conseguir un trabajo.

7 |

Estos ejercicios te van a ayudar a prepararte para futuras entrevistas tecnicas , aprender o repasar conceptos y como encararlos. Son ejercicios de entrevistas reales.

8 |
9 |
10 |

Ejercicios

11 | 12 | - [01-FindNeedle](/Ejercicios/01-FindNeedle/) 13 | - [02-SumArray](/Ejercicios/02-SumArray/) 14 | - [03-MaxValue](/Ejercicios/03-MaxValue/) 15 | - [04-MultidimensionalSumArray](/Ejercicios/04-MultidimensionalSumArray) 16 | - [05-MinStack](Ejercicios/05-MinStack/) 17 | - [06-HasBalanceBrackets](/Ejercicios/06-HasBalanceBrackets/) 18 | - [07-SolveGraph](/Ejercicios/07-SolveGraph/) 19 | - [08-FindWordStartingWith](/Ejercicios/08-FindWordStartingWith/) 20 | - [09-BinaryToDecimal](Ejercicios/09-BinaryToDecimal/) 21 | - [10-DecimalToBinary](Ejercicios/10-DecimalToBynary/) 22 | - [11-ClockMinuteAdder](/Ejercicios/11-ClockMinuteAdder/) 23 | - [12-Intersection](/Ejercicios/12-Intersection/) 24 | - [13-SubSetSum](/Ejercicios/13-SubSetSum/) 25 | - [14-LongestIncreasingSubSequence](Ejercicios/14-LongestIncreasingSubSequence/) 26 | - [15-SpyOn](Ejercicios/15-SpyOn/) 27 | - [16-Curry](Ejercicios/16-Curry/) 28 |
29 | -------------------------------------------------------------------------------- /images/binary-decimal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/binary-decimal.png -------------------------------------------------------------------------------- /images/emoticon_duda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/emoticon_duda.png -------------------------------------------------------------------------------- /images/emoticon_gafas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/emoticon_gafas.png -------------------------------------------------------------------------------- /images/fantino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/fantino.png -------------------------------------------------------------------------------- /images/grafico_complejidad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/grafico_complejidad.png -------------------------------------------------------------------------------- /images/graph 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/graph 1.png -------------------------------------------------------------------------------- /images/graph 2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/graph 2.png -------------------------------------------------------------------------------- /images/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/graph.png -------------------------------------------------------------------------------- /images/perro_programador.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/perro_programador.png -------------------------------------------------------------------------------- /images/sumArray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/sumArray.png -------------------------------------------------------------------------------- /images/sumArray_true_false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tech-talently/tech-interview--javascript-ssr-sr/2570b4034d24d8e360fffa18aebcd63f138f575f/images/sumArray_true_false.png --------------------------------------------------------------------------------