├── .editorconfig ├── .eslintrc ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── feature_request.md │ └── new_algorithm.yml ├── pull_request_template.md └── workflows │ └── Ci.yml ├── .gitignore ├── .husky └── pre-commit ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── SECURITY.md ├── a.excalidraw ├── coverage ├── clover.xml ├── coverage-final.json ├── lcov-report │ ├── algorithms │ │ ├── Maths │ │ │ └── CoPrime │ │ │ │ ├── CoPrime.ts.html │ │ │ │ └── index.html │ │ ├── ciphers │ │ │ ├── CaesarCipher │ │ │ │ ├── CaesarCipher.ts.html │ │ │ │ └── index.html │ │ │ └── MorseCipher │ │ │ │ ├── MorseCipher.ts.html │ │ │ │ └── index.html │ │ ├── search │ │ │ ├── BinarySearch │ │ │ │ ├── BinarySearch.ts.html │ │ │ │ └── index.html │ │ │ └── DoubleLinearSearchRecursion │ │ │ │ ├── DoubleLinearSearchRecursion.ts.html │ │ │ │ └── index.html │ │ └── sorts │ │ │ ├── GnomeSort │ │ │ ├── GnomeSort.ts.html │ │ │ └── index.html │ │ │ └── QuickSort │ │ │ ├── QuickSort.ts.html │ │ │ └── index.html │ ├── base.css │ ├── block-navigation.js │ ├── dataStructures │ │ └── linkedList │ │ │ ├── index.html │ │ │ ├── linkedList.ts.html │ │ │ └── linkedListNode.ts.html │ ├── favicon.png │ ├── index.html │ ├── prettify.css │ ├── prettify.js │ ├── sort-arrow-sprite.png │ ├── sorter.js │ └── utils │ │ ├── Comparator.ts.html │ │ └── index.html └── lcov.info ├── jest.config.ts ├── package-lock.json ├── package.json ├── public └── TS.png ├── scripts └── ValidateDirectory.mjs ├── src ├── algorithms │ ├── Maths │ │ ├── CoPrime │ │ │ ├── CoPrime.ts │ │ │ └── __tests__ │ │ │ │ └── CoPrime.test.ts │ │ └── EulerTotient │ │ │ ├── __tests__ │ │ │ └── CoPrime.test.ts │ │ │ └── eulerTotient.ts │ ├── ciphers │ │ ├── CaesarCipher │ │ │ ├── CaesarCipher.ts │ │ │ └── __tests__ │ │ │ │ └── CaesarCipher.test.ts │ │ └── MorseCipher │ │ │ ├── MorseCipher.ts │ │ │ └── __tests__ │ │ │ └── MorseCipher.test.ts │ ├── search │ │ ├── BinarySearch │ │ │ ├── BinarySearch.ts │ │ │ └── __tests__ │ │ │ │ └── BinarySearch.test.ts │ │ └── DoubleLinearSearchRecursion │ │ │ ├── DoubleLinearSearchRecursion.ts │ │ │ └── __tests__ │ │ │ └── DoubleLinearSearchRecursion.test.ts │ └── sorts │ │ ├── GnomeSort │ │ ├── GnomeSort.ts │ │ └── __tests__ │ │ │ └── GnomeSort.test.ts │ │ └── QuickSort │ │ ├── QuickSort.ts │ │ └── __tests__ │ │ └── QuickSort.test.ts ├── dataStructures │ └── linkedList │ │ ├── __tests__ │ │ ├── linkedList.test.ts │ │ └── linkedListNode.test.ts │ │ ├── linkedList.ts │ │ └── linkedListNode.ts └── utils │ └── Comparator.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended" 11 | ], 12 | "rules": { 13 | "@typescript-eslint/no-inferrable-types": "off", 14 | "quotes": ["error", "double"], 15 | "curly": "error", 16 | "no-empty": "error", 17 | "@typescript-eslint/no-explicit-any": ["error", { "fixToUnknown": true }], 18 | "@typescript-eslint/no-unused-vars": "error", 19 | "semi": ["error", "always"], 20 | "no-trailing-spaces": ["error", { "ignoreComments": true }], 21 | "keyword-spacing": ["error", { "before": true }], 22 | "space-before-blocks": ["error", "always"], 23 | "space-infix-ops": ["error", { "int32Hint": false }], 24 | "object-curly-spacing": ["error", "always"], 25 | "no-multi-spaces": "error", 26 | "comma-spacing": ["error", { "before": false, "after": true }] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Bryan-Herrera-DEV -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: bryan_herrera_dev 4 | custom: ['https://www.paypal.com/paypalme/bryaneliasherrera'] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: 'Crear un informe que nos ayude a mejorar' 3 | title: '[BUG]: ' 4 | labels: ['bug'] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: '### Asegurese de que su tema no es un duplicado y de que sigue nuestras [directrices de contribucion](https://github.com/Bryan-Herrera-DEV/Algorithms-Typescript/blob/main/CONTRIBUTING.md)' 9 | - type: textarea 10 | id: description 11 | attributes: 12 | label: Descricion 13 | description: Explica cual es el problema. 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: expectedbhv 18 | attributes: 19 | label: Comportamiento esperado 20 | description: Describa cual era el comportamiento esperado 21 | validations: 22 | required: true 23 | - type: textarea 24 | id: actualbhv 25 | attributes: 26 | label: Comportamiento actual 27 | description: Describe lo que realmente ocurre. 28 | validations: 29 | required: true 30 | - type: textarea 31 | id: steps 32 | attributes: 33 | label: Pasos para reproducir (si es posible) 34 | description: Enumere los pasos para reproducir el comportamiento. 35 | placeholder: | 36 | 1. 37 | 2. 38 | 3. 39 | 4. 40 | validations: 41 | required: false 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Sugiera una idea para este proyecto 4 | title: "[FEAT]" 5 | labels: feat 6 | assignees: '' 7 | 8 | --- 9 | 10 | **¿Su solicitud de función está relacionada con un problema? Por favor, descríbalo.** 11 | Una descripción clara y concisa de cuál es el problema. Ej. Siempre me siento frustrado cuando [...] 12 | 13 | **Describa la solución que le gustaría** 14 | Una descripción clara y concisa de lo que quieres que ocurra. 15 | 16 | **Describa las alternativas que ha considerado** 17 | Una descripción clara y concisa de las soluciones o características alternativas que has considerado. 18 | 19 | **Contexto adicional** 20 | Añade aquí cualquier otro contexto o capturas de pantalla sobre la solicitud de función. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new_algorithm.yml: -------------------------------------------------------------------------------- 1 | name: New Algorithm 2 | description: 'Sugerir nuevos algoritmos, proponer mejoras, debatir nuevas ideas de algoritmos' 3 | title: '[NEW ALGORITHM]: ' 4 | labels: ['New Algorithm'] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | ## Esta plantilla de 'Issue' es para proponer nuevos algoritmos 10 | ## Asegurese de que su tema no es un duplicado y de que sigue nuestras [directrices de contribucion](https://github.com/Bryan-Herrera-DEV/Algorithms-Typescript/blob/main/CONTRIBUTING.md) 11 | - type: textarea 12 | id: description 13 | attributes: 14 | label: Descripcion del algoritmo 15 | description: Describa el algoritmo, su uso de manera sencilla y si es posible su complejidad matematica 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: examples 20 | attributes: 21 | label: Referencias y links 22 | description: Si usted ah tomado la idea del algoritmo ponga los enlaces aqui, o si tiene enlaces que expliquen de una manera mas extensa el mismo 23 | validations: 24 | required: false 25 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Describe tu cambio: 2 | 3 | - [ ] ¿Añade un algoritmo? 4 | - [ ] ¿Corregir un error en un algoritmo existente? 5 | - [ ] ¿Cambios en la documentación? 6 | - [ ] ¿Añade una nueva característica o mejora al core del proyecto? 7 | 8 | ### Checklist: 9 | 10 | - [ ] He leído [CONTRIBUTING.md](https://github.com/Bryan-Herrera-DEV/Algorithms-Typescript/blob/main/CONTRIBUTING.md). 11 | - [ ] Este pull request es todo mi trabajo - no he plagiado. Si hay codigo de otra persona lo eh mencionado. 12 | - [ ] Sé que los pull requests no serán fusionados si fallan las pruebas automatizadas. 13 | - [ ] Todos los nuevos archivos de TypeScript se colocan dentro de un directorio existente. 14 | - [ ] Todos los nombres de archivos deben usar el estilo UpperCamelCase (PascalCase). No debe haber espacios en los nombres de los archivos. 15 | -------------------------------------------------------------------------------- /.github/workflows/Ci.yml: -------------------------------------------------------------------------------- 1 | name: Testeando el proyecto 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | jobs: 8 | build: 9 | name: Estilo de código y pruebas 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: 18.12.1 17 | cache: npm 18 | 19 | - name: 📦 Instalando Dependencias 20 | run: npm ci 21 | 22 | - name: 🧪 Corriendo Todos los Test 23 | if: ${{ github.event_name == 'push' }} 24 | run: npm run test 25 | 26 | - name: 🧪 Ejecutar Test sólo para los archivos modificados 27 | if: ${{ github.event_name == 'pull_request' }} 28 | run: npm run test-changed 29 | 30 | - name: 💄 Estilo de codigo 31 | run: npm run style 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm run test-files 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Código de conducta para colaboradores 2 | ## Nuestro compromiso 3 | Nosotros, como miembros, colaboradores y líderes, nos comprometemos a hacer de la participación en nuestra comunidad una experiencia libre de acoso para todos, independientemente de la edad, el tamaño del cuerpo, la discapacidad visible o invisible, el origen étnico, las características sexuales, la identidad y expresión de género, el nivel de experiencia, la educación, el estatus socioeconómico, la nacionalidad, la apariencia personal, la raza, la religión o la identidad y orientación sexual. 4 | 5 | Nos comprometemos a actuar e interactuar de manera que contribuya a una comunidad abierta, acogedora, diversa, inclusiva y saludable. 6 | ## Nuestras normas 7 | 8 | Algunos ejemplos de comportamientos que contribuyen a crear un entorno positivo son: 9 | 10 | - Utilizar un lenguaje acogedor e inclusivo 11 | - Ser respetuoso con los diferentes puntos de vista y experiencias 12 | - Aceptar con gracia las críticas constructivas 13 | - Centrarse en lo que es mejor para la comunidad 14 | - Mostrar empatía hacia otros miembros de la comunidad 15 | 16 | Ejemplos de comportamiento inaceptable por parte de los participantes son: 17 | 18 | - El uso de lenguaje o imágenes sexualizadas y la atención o insinuaciones sexuales no deseadas 19 | - Trolling, comentarios insultantes/despectivos y ataques personales o políticos 20 | - Acoso público o privado 21 | - Publicar información privada de otros, como una dirección física o electrónica, sin permiso explícito 22 | - Otras conductas que puedan considerarse razonablemente inapropiadas en un entorno profesional 23 | - Utilizar o compartir código privado de la empresa, para fines personales o públicos externos 24 | 25 | ## Nuestras responsabilidades 26 | 27 | Los encargados del mantenimiento del proyecto son responsables de aclarar las normas de comportamiento aceptable y se espera que tomen medidas correctivas adecuadas y justas en respuesta a cualquier caso de comportamiento inaceptable. 28 | 29 | ## Ámbito de aplicación 30 | Este Código de Conducta se aplica en todos los espacios de la comunidad, y también se aplica cuando una persona representa oficialmente a la comunidad en espacios públicos. Ejemplos de representación de nuestra comunidad incluyen el uso de una dirección de correo electrónico oficial, la publicación a través de una cuenta oficial en las redes sociales, o la actuación como representante designado en un evento en línea o fuera de línea. 31 | 32 | ## Aplicación de la ley 33 | Los casos de comportamiento abusivo, acosador o inaceptable pueden ser denunciados a los líderes de la comunidad responsables de su cumplimiento en bryherrera55@gmail.com. Todas las quejas serán revisadas e investigadas de forma rápida y justa. 34 | 35 | Todos los responsables de la comunidad están obligados a respetar la privacidad y la seguridad del denunciante de cualquier incidente. 36 | 37 | ## Directrices de aplicación 38 | Los líderes comunitarios seguirán estas Directrices de Impacto Comunitario para determinar las consecuencias de cualquier acción que consideren que infringe este Código de Conducta: 39 | 40 | 1. Corrección 41 | Impacto en la comunidad: Uso de un lenguaje inapropiado u otro comportamiento considerado poco profesional o inoportuno en la comunidad. 42 | 43 | Consecuencia: Advertencia privada y por escrito de los líderes de la comunidad, en la que se aclara la naturaleza de la infracción y se explica por qué el comportamiento fue inapropiado. Puede solicitarse una disculpa pública. 44 | 45 | 2. Advertencia 46 | Impacto en la comunidad: Una violación a través de un único incidente o una serie de acciones. 47 | 48 | Consecuencia: Una advertencia con consecuencias para el comportamiento continuado. No se puede interactuar con las personas implicadas, incluida la interacción no solicitada con los encargados de hacer cumplir el Código de Conducta, durante un periodo de tiempo determinado. Esto incluye evitar las interacciones en los espacios de la comunidad, así como en canales externos como las redes sociales. La violación de estos términos puede llevar a una prohibición temporal o permanente. 49 | 50 | 3. Prohibición temporal 51 | Impacto en la comunidad: Una violación grave de las normas de la comunidad, incluyendo un comportamiento inapropiado sostenido. 52 | 53 | Consecuencia: Prohibición temporal de cualquier tipo de interacción o comunicación pública con la comunidad durante un periodo de tiempo determinado. Durante este periodo no se permite ninguna interacción pública o privada con las personas implicadas, incluyendo la interacción no solicitada con los encargados de hacer cumplir el Código de Conducta. La violación de estos términos puede llevar a una prohibición permanente. 54 | 55 | 4. Prohibición permanente 56 | Impacto en la comunidad: Demostrar un patrón de violación de las normas de la comunidad, incluyendo el comportamiento inapropiado sostenido, el acoso de un individuo, o la agresión hacia o el desprecio de clases de individuos. 57 | 58 | Consecuencia: Prohibición permanente de cualquier tipo de interacción pública dentro de la comunidad. 59 | 60 | ## Atribución 61 | 62 | El presente Código de Conducta es una adaptación de [Contributor Covenant][homepage], 63 | version 2.0, disponible en 64 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 65 | 66 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 67 | enforcement ladder](https://github.com/mozilla/diversity). 68 | 69 | [homepage]: https://www.contributor-covenant.org 70 | 71 | For answers to common questions about this code of conduct, see the FAQ at 72 | https://www.contributor-covenant.org/faq. Translations are available at 73 | https://www.contributor-covenant.org/translations. 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Directrices de contribución 2 | ## Antes de contribuir 3 | ¡Bienvenido a Algorithms-Typescript Español! Antes de enviar tus `pull requests`, asegúrate de leer todas las directrices. Si tienes alguna duda sobre la guía de contribución, no dudes en exponerla claramente en un issue. 4 | 5 | ## Contribuyendo 6 | ### Colaborador 7 | 8 | ¡Estamos muy contentos de que consideres implementar algoritmos y estructuras de datos para otros! Este repositorio es referenciado y utilizado por estudiantes de todo el mundo. Siendo uno de nuestros contribuidores, aceptas y confirmas que: 9 | - Has hecho tu trabajo - el plagio no está permitido. 10 | - Cualquier trabajo plagiado no será fusionado. 11 | - Si el codigo es tomado de otro repositorio, se debe dar crédito al autor original. 12 | - Su trabajo será distribuido bajo licencia GNU una vez que su `pull request` sea fusionada. 13 | - Su trabajo enviado debe cumplir con nuestros estilos y estándares. 14 | 15 | **Las nuevas implementaciones** son bienvenidas. Por ejemplo, nuevas soluciones a un problema, diferentes representaciones de una estructura de datos gráfica o diseños de algoritmos con diferente complejidad. 16 | 17 | La mejora de los comentarios y la realización de pruebas adecuadas también son bienvenidas. 18 | 19 | ### Contribucion 20 | Apreciamos cualquier contribución, desde la corrección de errores gramaticales hasta la implementación de algoritmos complejos. Por favor, lee esta sección si vas a contribuir con tu trabajo. 21 | 22 | Si envías un `pull request` que resuelve un problema abierto, por favor ayúdanos a mantener nuestra lista de problemas pequeña añadiendo `fixes: #{$ISSUE_NO}` a tu `commit`. GitHub utilizará esta etiqueta para cerrar automáticamente la incidencia si su PR se fusiona. 23 | 24 | #### ¿Qué es un algoritmo? 25 | Un algoritmo es una o más funciones (o clases) que: 26 | 27 | - toman una o más entradas. 28 | - realizan algunos cálculos internos o manipulaciones de datos. 29 | - devuelven una o más salidas. 30 | - tienen un mínimo de efectos secundarios. 31 | 32 | Los algoritmos deben ser empaquetados de manera que sea fácil para los lectores ponerlos en programas más grandes. 33 | 34 | #### Los algoritmos deben: 35 | 36 | - tener nombres intuitivos de clases y funciones que dejen claro su propósito a los lectores. 37 | - Utilizar convenciones de nomenclatura de JavaScript/TypeScript y nombres de variables intuitivos para facilitar la comprensión. 38 | - ser flexibles para tomar diferentes valores de entrada. 39 | - lanzar excepciones de JavaScript (RangeError, etc.) en caso de valores de entrada erróneos. 40 | 41 | Los algoritmos de este repositorio no deben ser ejemplos de cómo hacer los paquetes de JavaScript existentes. En su lugar, deben realizar cálculos o manipulaciones internas para convertir los valores de entrada en diferentes valores de salida. Estos cálculos o manipulaciones pueden utilizar tipos de datos, clases o funciones de paquetes JavaScript existentes, pero cada algoritmo de este repositorio debe aportar un valor único. 42 | 43 | #### Convención de nomenclatura de 44 | 45 | - Los nombres de los archivos deben utilizar el estilo UpperCamelCase (PascalCase). 46 | - No debe haber espacios en los nombres de los archivos. 47 | - **Ejemplo:** `UserProfile.js` está permitido pero `userprofile.js`,`Userprofile.js`,`user-Profile.js`,`userProfile.js` no lo están. 48 | 49 | #### Sistema de módulos 50 | Utilizamos el sistema ES Module, que aporta un sistema de módulos oficial y estandarizado a JavaScript. 51 | 52 | A grandes rasgos, significa que tendrás que utilizar declaraciones `export` e `import` en lugar de `module.exports` y `require()`. 53 | 54 | #### Probando 55 | Asegúrese de que su código funciona. ¿Cuándo fue la última vez que hiciste un cambio en el código, tu construcción falló y la mitad de tu aplicación dejó de funcionar? La mía fue la semana pasada. Escribir pruebas para nuestros algoritmos nos ayudará a asegurar que las implementaciones son herméticas incluso después de múltiples correcciones y cambios de código. 56 | 57 | Utilizamos Jest para ejecutar pruebas unitarias en nuestros algoritmos. Proporciona una manera muy legible y expresiva para estructurar su código de prueba. 58 | 59 | Se aconseja que el archivo del algoritmo (módulo) no contenga ningún código "vivo", sino que sólo exporte la(s) función(es) necesaria(s) para ejecutar el algoritmo. Su código de prueba puede importar esas funciones, llamarlas con los parámetros adecuados e inspeccionar el resultado. Ejemplo: [RatInAMaze.test.js](https://github.com/TheAlgorithms/JavaScript/blob/master/Backtracking/tests/RatInAMaze.test.js). 60 | 61 | Por favor, absténgase de utilizar la consola en su implementación Y código de prueba. 62 | 63 | Primero debes instalar todas las dependencias usando 64 | 65 | ```bash 66 | npm install 67 | ``` 68 | Puedes (¡y deberías!) ejecutar todas las pruebas localmente antes de confirmar los cambios: 69 | ```bash 70 | npm test 71 | ``` 72 | Si quieres ahorrar algo de tiempo y sólo ejecutar una prueba específica: 73 | ```bash 74 | # Esto ejecutará cualquier archivo de prueba cuyo nombre contenga "koch" (no es necesario especificar la ruta de la carpeta) 75 | npm test -- koch 76 | ``` 77 | También puedes iniciar Jest en modo "watch": 78 | ```bash 79 | npm test -- --watchAll 80 | ``` 81 | También hemos preparado un script de ayuda que ejecuta las pruebas sólo para los archivos modificados: 82 | ```bash 83 | npm run test-changed 84 | ``` 85 | Esto ejecutará todas las pruebas y vigilará los archivos fuente y de prueba en busca de cambios. Cuando se realice un cambio, las pruebas se ejecutarán de nuevo. 86 | #### Formato de los `commit` 87 | - Es preferible utilizar el siguiente formato: `[ ](): descripcion brebe`. Si es necesario, ponga cualquier información extra en la descripción. 88 | - Para los emojis usar la lista [emojis de gitmoji](https://gitmoji.dev). 89 | 90 | - Los tipos de commit incluyen (pero no se limitan a): 91 | - docs: Cambios sólo en la documentación 92 | - feat: Una nueva característica 93 | - fix: Una corrección de errores 94 | - testing: Añadir o arreglar pruebas 95 | - **Ejemplos:** 96 | - `[✨ feat]`: añadir el algoritmo quicksort 97 | - `[🐛 fix](#10)`: mensaje de error incorrecto 98 | - `[📝 docs]`: añadir directrices de contribución 99 | - `[✅ test]`: añadir test para el algoritmo quicksort 100 | 101 | #### Estilo de codificación 102 | Para maximizar la legibilidad y la corrección de nuestro código, requerimos que los nuevos envíos sigan el estilo estándar de JavaScript/Typescript. 103 | 104 | Antes de enviar el código, ejecute: 105 | ```bash 106 | npm run style 107 | ``` 108 | para aplicar el estilo de codificación (en los casos en que pueda hacerse automáticamente). Si se muestra un error, por favor, averigüe qué es lo que está mal, arréglelo y ejecute standard de nuevo. 109 | 110 | Algunas (pero no todas) de las cosas a tener en cuenta: 111 | 112 | - Utilice camelCase con el carácter inicial en minúscula para los nombres de los identificadores (variables y funciones). 113 | - Los nombres comienzan con una letra. 114 | - Siga la indentación del código: Utilice siempre 2 espacios para la sangría de los bloques de código. 115 | - Asegurese de que su código no contenga espacios en blanco innecesarios. 116 | - No olvide que toda declaración debe terminar con un punto y coma. 117 | - Siempre use los types de TypeScript para las variables y funciones. No utilice `any` o `unknow` a menos que sea absolutamente necesario. 118 | ```typescript 119 | function sumOfArray(arrayOfNumbers: number[]): number { 120 | let suma: number = 0 121 | 122 | for (let i: numver = 0; i < arrayOfNumbers.length; i++) { 123 | suma += arrayOfNumbers[i] 124 | } 125 | return suma 126 | ``` 127 | - Evite el uso de variables globales y evite `==`. 128 | - Utiliza `let` en lugar de `var`. 129 | - Por favor, absténgase de utilizar `console.log` o cualquier otro método de consola. 130 | - No utilices en absoluto `alert`. 131 | - Recomendamos encarecidamente el uso de ECMAScript 6. 132 | - Evite importar bibliotecas externas para algoritmos básicos. Sólo utilice esas bibliotecas para los algoritmos complicados. 133 | - Y lo más importante: 134 | - Sé coherente en el uso de estas directrices cuando envíes tu proyecto. 135 | - ¡Feliz coding! 136 | 137 | Esta guía está basada en [Javascript Contributing](https://github.com/TheAlgorithms/JavaScript/blob/master/CONTRIBUTING.md) y fue traducida por [Bryan Herrera](https://github.com/Bryan-Herrera-DEV) -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2022 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

Algorithms-Typescript Español

3 |

Repositorio que implementa varios algoritmos y estructuras de datos en TypeScript. Explicados en español

4 |

⚠️ Nota: Estas implementaciones son sólo para fines demostrativos/educativos. Las implementaciones dedicadas de estos algoritmos y estructuras de datos son mucho mejores por razones de rendimiento y seguridad.

5 |
6 |
7 |
8 |
9 | 10 | GitHub package.json dependency version (prod) 11 | 12 | 13 | Codacy grade 14 | 15 |
16 |
17 |
18 | 19 | ## Algoritmos 20 | Un algoritmo es una especificación inequívoca de cómo resolver una clase de problemas. Es un conjunto de reglas que definen con precisión una secuencia de operaciones. 21 | 22 | `A` - Avanzados, `I` - Intermedios, `B` - Básicos 23 | 24 |
Ordenamiento 25 |
26 | 27 | - `B` - [Gnome Sort](/src/algorithms/sorts/GnomeSort/) - [Video](https://www.youtube.com/watch?v=00pu8usw2Ho) 28 | - `I` - [Quick Sort](/src/algorithms/sorts/QuickSort/) - [Video](https://www.youtube.com/watch?v=O15QndpLHGE) 29 |
30 | 31 |
Cifrado 32 |
33 | 34 | - `I` - [Caesar Cipher](/src/algorithms/ciphers/CaesarCipher/) - [Video](https://www.youtube.com/watch?v=2JS6t3R8gFQ) 35 | - `B` - [Morse Cipher](/src/algorithms/ciphers/MorseCipher/) 36 |
37 | 38 |
Busqueda 39 |
40 | 41 | - `B` - [Binary Search](/src/algorithms/search/BinarySearch/) 42 | - `B` - [Double Linear Search Recursion](/src/algorithms/search/DoubleLinearSearchRecursion/) 43 |
44 | 45 |
Matemáticos 46 |
47 | 48 | - `B` - [Co Prime Integers](/src/algorithms/Maths/CoPrime/) 49 | - `B` - [Euler Totient](/src/algorithms/Maths/EulerTotient/) 50 | 51 |
52 | 53 | ## Estructuras de datos 54 | Esencialmente, una estructura de datos es un conjunto de elementos de datos y las relaciones entre ellos, que se utilizan para representar y almacenar información. 55 | 56 | `A` - Avanzados, `I` - Intermedios, `B` - Básicos 57 | 58 |
Estructuras de datos 59 |
60 | 61 | - `I` - [Linked List](/src/dataStructures/linkedList/) - [Video](https://www.youtube.com/watch?v=PBhbRcPOEMA) 62 |
63 | 64 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Política de seguridad 2 | 3 | ## Versiones compatibles 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Soportada | 9 | | ------- | ------------------ | 10 | | 1.0.0 | :white_check_mark: | 11 | 12 | ## Informar de una vulnerabilidad 13 | 14 | Utiliza esta sección para indicar a los usuarios cómo informar de una vulnerabilidad. 15 | 16 | Dígales dónde dirigirse, con qué frecuencia pueden esperar recibir una actualización sobre una 17 | vulnerabilidad reportada, qué esperar si la vulnerabilidad es aceptada o 18 | se rechaza, etc. 19 | -------------------------------------------------------------------------------- /a.excalidraw: -------------------------------------------------------------------------------- 1 | { 2 | "type": "excalidraw", 3 | "version": 2, 4 | "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", 5 | "elements": [ 6 | { 7 | "id": "ui5156mVSL1no3r0aqS3a", 8 | "type": "text", 9 | "x": 572.0175170898438, 10 | "y": 295.83001708984375, 11 | "width": 299.57977294921875, 12 | "height": 25, 13 | "angle": 0, 14 | "strokeColor": "#e67700", 15 | "backgroundColor": "transparent", 16 | "fillStyle": "hachure", 17 | "strokeWidth": 1, 18 | "strokeStyle": "solid", 19 | "roughness": 1, 20 | "opacity": 100, 21 | "groupIds": [], 22 | "roundness": null, 23 | "seed": 380312901, 24 | "version": 62, 25 | "versionNonce": 1527565259, 26 | "isDeleted": false, 27 | "boundElements": [], 28 | "updated": 1681592799863, 29 | "link": null, 30 | "locked": false, 31 | "text": "Esta es mi clave: 5544332211", 32 | "fontSize": 20, 33 | "fontFamily": 1, 34 | "textAlign": "left", 35 | "verticalAlign": "top", 36 | "baseline": 17, 37 | "containerId": null, 38 | "originalText": "Esta es mi clave: 5544332211", 39 | "lineHeight": 1.25 40 | }, 41 | { 42 | "id": "_tRN6cyAHfkq4OvEoJnha", 43 | "type": "arrow", 44 | "x": 593.280029296875, 45 | "y": 345.60003662109375, 46 | "width": 2.54248046875, 47 | "height": 91.52999877929688, 48 | "angle": 0, 49 | "strokeColor": "#e67700", 50 | "backgroundColor": "transparent", 51 | "fillStyle": "hachure", 52 | "strokeWidth": 1, 53 | "strokeStyle": "solid", 54 | "roughness": 1, 55 | "opacity": 100, 56 | "groupIds": [], 57 | "roundness": { 58 | "type": 2 59 | }, 60 | "seed": 988377163, 61 | "version": 40, 62 | "versionNonce": 747475717, 63 | "isDeleted": false, 64 | "boundElements": null, 65 | "updated": 1681592799863, 66 | "link": null, 67 | "locked": false, 68 | "points": [ 69 | [ 70 | 0, 71 | 0 72 | ], 73 | [ 74 | 2.54248046875, 75 | 91.52999877929688 76 | ] 77 | ], 78 | "lastCommittedPoint": null, 79 | "startBinding": null, 80 | "endBinding": null, 81 | "startArrowhead": null, 82 | "endArrowhead": "arrow" 83 | }, 84 | { 85 | "id": "W8_qMaw5EZXdqSVRc-uxt", 86 | "type": "text", 87 | "x": 579.9824829101562, 88 | "y": 460.16998291015625, 89 | "width": 209.87977600097656, 90 | "height": 25, 91 | "angle": 0, 92 | "strokeColor": "#e67700", 93 | "backgroundColor": "transparent", 94 | "fillStyle": "hachure", 95 | "strokeWidth": 1, 96 | "strokeStyle": "solid", 97 | "roughness": 1, 98 | "opacity": 100, 99 | "groupIds": [], 100 | "roundness": null, 101 | "seed": 1688897131, 102 | "version": 42, 103 | "versionNonce": 1290552363, 104 | "isDeleted": false, 105 | "boundElements": null, 106 | "updated": 1681592753196, 107 | "link": null, 108 | "locked": false, 109 | "text": "-... -.. -- .... --.-...-----", 110 | "fontSize": 20, 111 | "fontFamily": 1, 112 | "textAlign": "left", 113 | "verticalAlign": "top", 114 | "baseline": 17, 115 | "containerId": null, 116 | "originalText": "-... -.. -- .... --.-...-----", 117 | "lineHeight": 1.25 118 | }, 119 | { 120 | "id": "xE0-gCWEAlbf7VbxVSyD4", 121 | "type": "arrow", 122 | "x": 773.6175537109375, 123 | "y": 462.8700256347656, 124 | "width": 1.10247802734375, 125 | "height": 121.59002685546875, 126 | "angle": 0, 127 | "strokeColor": "#e67700", 128 | "backgroundColor": "transparent", 129 | "fillStyle": "hachure", 130 | "strokeWidth": 1, 131 | "strokeStyle": "solid", 132 | "roughness": 1, 133 | "opacity": 100, 134 | "groupIds": [], 135 | "roundness": { 136 | "type": 2 137 | }, 138 | "seed": 1104079461, 139 | "version": 18, 140 | "versionNonce": 1853210475, 141 | "isDeleted": false, 142 | "boundElements": null, 143 | "updated": 1681592805071, 144 | "link": null, 145 | "locked": false, 146 | "points": [ 147 | [ 148 | 0, 149 | 0 150 | ], 151 | [ 152 | 1.10247802734375, 153 | -121.59002685546875 154 | ] 155 | ], 156 | "lastCommittedPoint": null, 157 | "startBinding": null, 158 | "endBinding": null, 159 | "startArrowhead": null, 160 | "endArrowhead": "arrow" 161 | } 162 | ], 163 | "appState": { 164 | "gridSize": null, 165 | "viewBackgroundColor": "#0d0d0d" 166 | }, 167 | "files": {} 168 | } -------------------------------------------------------------------------------- /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 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 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 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/Maths/CoPrime/CoPrime.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/Maths/CoPrime/CoPrime.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / algorithms/Maths/CoPrime CoPrime.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19 85 | 20 86 | 21 87 | 22 88 | 23 89 | 24 90 | 25 91 | 26 92 | 27 93 | 28 94 | 29 95 | 30 96 | 31 97 | 32 98 | 33 99 | 34 100 | 35 101 | 36  102 |   103 |   104 |   105 |   106 |   107 |   108 |   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 |  * @function CoPrime
138 |  * @description Es un algoritmo matemático que nos permite validar si los factores primos de dos números tienen un factor común entre si, el cual es el 1.
139 |  * Tambien se le conoce como 'Primos Relativos' y podemos hallarlo con sus factores primos o con su MCD.
140 |  * @param: {number} firstNumber - Primer número a comparar.
141 |  * @param: {number} secondNumber - Segundo número a comparar.
142 |  * @return: {boolean} - Devuelve true si los números son 'Co-Primos', false en caso contrario.
143 |  */
144 |  
145 | // Aqui haremos uso del Algoritmos Euclides para encontrar el MCD (Máximo común divisor) de dos números.
146 | // Explicacion
147 | /*
148 | |  Q  |  A  |  B  |  R  |
149 | |  2  |  33 |  12 |  9  | Resto de (12 / 33) = 9
150 | |  1  |  12 |  9  |  3  | Resto de (9 / 12 ) = 3
151 | |  3  |  9  |  3  |  0  | Resto de (3 / 9 ) = 0
152 | |  x  |  3  |  0  |  x  | Cuando B = 0 sabemos que el MCD es A
153 | */
154 |  
155 | const EuclideanMCD = (a: number, b: number): number => {
156 |   Iif (b === 0) {
157 |     return a;
158 |   }
159 |   return EuclideanMCD(b, a % b); // vamos a usar retornar la misma funcion hasta que se cumpla la valdiacion previa, uso de recursividad
160 | };
161 |  
162 |  
163 | // La manera en la que lo hallaremos es con el algoritmo de Euclides y validar su resultado con el 1, si es igual a 1 entonces son 'Co-Primos'
164 | export const CoPrime = (firstNumber: number, secondNumber: number): boolean | TypeError => {
165 |   // Validamos que ambos parametros sean numeros
166 |   Iif (typeof firstNumber !== "number" || typeof secondNumber !== "number") {
167 |     return new TypeError("Argument is not a number.");
168 |   }
169 |   return EuclideanMCD(firstNumber, secondNumber) === 1;
170 | };
171 |  
172 | 173 |
174 |
175 | 180 | 181 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/Maths/CoPrime/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/Maths/CoPrime 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/Maths/CoPrime

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
CoPrime.ts 84 |
85 |
0%0/90%0/40%0/20%0/8
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/ciphers/CaesarCipher/CaesarCipher.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/ciphers/CaesarCipher/CaesarCipher.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / algorithms/ciphers/CaesarCipher CaesarCipher.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19 85 | 20 86 | 21 87 | 22 88 | 23 89 | 24 90 | 25 91 | 26 92 | 27 93 | 28 94 | 29 95 | 30 96 | 31 97 | 32 98 | 33 99 | 34 100 | 35 101 | 36 102 | 37 103 | 38 104 | 39  105 |   106 |   107 |   108 |   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 |  * @function CaesarCipher
144 |  * @description: En criptografía, el cifrado César, también conocido como cifrado del César, cifrado por desplazamiento. Es un tipo de cifrado por sustitución en el que cada letra del texto plano se sustituye por una letra en un número fijo de posiciones hacia abajo del alfabeto. Por ejemplo, con un desplazamiento a la izquierda de 3, la D sería sustituida por la A, la E se convertiría en la B, y así sucesivamente.
145 |  * @param: str {string} - Cadena a encriptar o a desencriptar
146 |  * @param: rotation {number} - Numero que va a definir el desplazamiento del texto
147 |  * @param: encrypt {boolean} - Si es true, encriptamos, si es false, desencriptamos
148 |  * @return: {string} - cadena desencriptada i encriptada dependiendo el caso
149 |  */
150 |  
151 |  
152 | export const CaesarCipher = (str: string, rotation: number, encrypt: boolean = true): string => {
153 |   Iif (typeof str !== "string" || !Number.isInteger(rotation) || rotation <= 0 || typeof encrypt !== "boolean") {
154 |     throw new TypeError("Argumentos invalidos");
155 |   }
156 |  
157 |   rotation = encrypt ? rotation : -(rotation);
158 |  
159 |   const alphabets = new Array(26)
160 |     .fill(0)
161 |     .map((_ :string, index: number) => String.fromCharCode(97 + index));
162 |  
163 |   const cipherMap = alphabets.reduce(
164 |     (map, char, index) => {
165 |       Iif (((rotation + index) % 26) < 0) {
166 |         return map.set(char, alphabets[26 + ((rotation + index) % 26)]);
167 |       }
168 |       return map.set(char, alphabets[(rotation + index) % 26]);
169 |     },
170 |     new Map()
171 |   );
172 |  
173 |   return str.replace(/[a-z]/gi, (char: string): string => {
174 |       Iif (/[A-Z]/.test(char)) {
175 |         return cipherMap.get(char.toLocaleLowerCase()).toUpperCase();
176 |       }
177 |       return cipherMap.get(char);
178 |   });
179 | };
180 |  
181 | 182 |
183 |
184 | 189 | 190 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/ciphers/CaesarCipher/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/ciphers/CaesarCipher 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/ciphers/CaesarCipher

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
CaesarCipher.ts 84 |
85 |
0%0/150%0/100%0/40%0/14
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/ciphers/MorseCipher/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/ciphers/MorseCipher 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/ciphers/MorseCipher

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
MorseCipher.ts 84 |
85 |
0%0/160%0/30%0/20%0/14
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/search/BinarySearch/BinarySearch.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/search/BinarySearch/BinarySearch.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / algorithms/search/BinarySearch BinarySearch.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19 85 | 20 86 | 21 87 | 22 88 | 23 89 | 24 90 | 25 91 | 26 92 | 27 93 | 28 94 | 29 95 | 30 96 | 31 97 | 32 98 | 33 99 | 34 100 | 35 101 | 36 102 | 37 103 | 38 104 | 39 105 | 40 106 | 41 107 | 42 108 | 43 109 | 44 110 | 45 111 | 46 112 | 47 113 | 48 114 | 49 115 | 50 116 | 51 117 | 52 118 | 53 119 | 54 120 | 55 121 | 56  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 |   158 |   159 |   160 |   161 |   162 |   163 |   164 |   165 |   166 |   167 |   168 |   169 |   170 |   171 |   172 |   173 |   174 |   175 |   176 |  
/**
177 |  * @function BinarySearch
178 |  * @description algoritmo de búsqueda binaria (implementaciones iterativas y recursivas) para una matriz ordenada.
179 |  * El algoritmo busca un valor específico en una matriz ordenada en tiempo logarítmico.
180 |  * Repetidamente divide por la mitad la porción de la lista que podría contener el ítem,
181 |  *  hasta que ha reducido los posibles índices a sólo uno.
182 |  *
183 |  * @param: {number[]} array - Lista ordenada de numeros
184 |  * @param: {number} target - Numero a buscar
185 |  * @return: {number} - índice del número de destino en la lista, o -1 si no se encuentra
186 |  */
187 |  
188 | export const binarySearchIterative = (array: number[], target: number): number => {
189 |   Iif (array.length === 0) {return -1;}
190 |  
191 |   // declarar punteros para los índices de inicio, medio y final
192 |   let start = 0,
193 |       end = array.length - 1,
194 |       middle = (start + end) >> 1;
195 |  
196 |   // asegúrese de que el objetivo está dentro de los límites de la matriz
197 |   Iif (target < array[start] || target > array[end]) {return -1;}
198 |  
199 |   while (array[middle] !== target && start <= end) {
200 |       // si el objetivo es menor que el valor medio, mueve el puntero final para que sea medio -1 para reducir el espacio de búsqueda
201 |       // en caso contrario, mueve el puntero de inicio para que sea medio + 1
202 |       if (target < array[middle])
203 |           {end = middle - 1;}
204 |       else
205 |           {start = middle + 1;}
206 |       // volver a declarar el índice medio cuando la ventana de búsqueda cambia
207 |       middle = (start + end) >> 1;
208 |   }
209 |   // devuelve el índice medio si es igual al objetivo
210 |   return array[middle] === target ? middle : -1;
211 | };
212 |  
213 |  
214 | export const binarySearchRecursive = (array: number[], target: number, start = 0, end = array.length - 1): number => {
215 |   Iif (array.length === 0) {return -1;}
216 |  
217 |   // asegúrese de que el objetivo está dentro de los límites de la matriz
218 |   Iif (target < array[start] || target > array[end]) {return -1;}
219 |  
220 |   const middle = (start + end) >> 1;
221 |  
222 |   Iif (array[middle] === target) {return middle;} // número encontrado
223 |   Iif (start > end) {return -1;} // número no encontrado
224 |  
225 |   // si el objetivo es menor que el valor medio, mueve el puntero final para que sea medio -1 para reducir el espacio de búsqueda
226 |   // en caso contrario, mueve el puntero de inicio para que sea medio + 1
227 |   return target < array[middle]
228 |       ? binarySearchRecursive(array, target, start, middle - 1)
229 |       : binarySearchRecursive(array, target, middle + 1, end);
230 | };
231 |  
232 | 233 |
234 |
235 | 240 | 241 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/search/BinarySearch/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/search/BinarySearch 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/search/BinarySearch

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
BinarySearch.ts 84 |
85 |
0%0/270%0/200%0/20%0/19
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/search/DoubleLinearSearchRecursion/DoubleLinearSearchRecursion.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/search/DoubleLinearSearchRecursion/DoubleLinearSearchRecursion.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / algorithms/search/DoubleLinearSearchRecursion DoubleLinearSearchRecursion.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19 85 | 20 86 | 21 87 | 22 88 | 23 89 | 24 90 | 25 91 | 26 92 | 27 93 | 28 94 | 29  95 |   96 |   97 |   98 |   99 |   100 |   101 |   102 |   103 |   104 |   105 |   106 |   107 |   108 |   109 |   110 |   111 |   112 |   113 |   114 |   115 |   116 |   117 |   118 |   119 |   120 |   121 |   122 |  
/**
123 |  * @function DoubleLinearSearchRecursion
124 |  * @description Una ligera mejora con respecto a la típica búsqueda lineal.
125 |  *
126 |  * @param: {number[]} list_data - la lista que se va a buscar
127 |  * @param: {number} clave - la clave a buscar
128 |  * @param: {number} left - índice del primer elemento
129 |  * @param: {number} right - el índice del último elemento
130 |  * @return: {number} - el índice del valor de la clave si se encuentra, -1 en caso contrario.
131 |  */
132 |  
133 | export const DoubleLinearSearchRecursion = (
134 |   list_data: number[],
135 |   clave: number,
136 |   left: number = 0,
137 |   right: number = 0
138 | ): number => {
139 |   right = right || list_data.length - 1;
140 |   if (left > right) {
141 |     return -1;
142 |   } else if (list_data[left] === clave) {
143 |     return left;
144 |   } else if (list_data[right] === clave) {
145 |     return right;
146 |   } else {
147 |     return DoubleLinearSearchRecursion(list_data, clave, left + 1, right - 1);
148 |   }
149 | };
150 |  
151 | 152 |
153 |
154 | 159 | 160 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/search/DoubleLinearSearchRecursion/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/search/DoubleLinearSearchRecursion 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/search/DoubleLinearSearchRecursion

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
DoubleLinearSearchRecursion.ts 84 |
85 |
0%0/100%0/100%0/10%0/9
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/sorts/GnomeSort/GnomeSort.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/sorts/GnomeSort/GnomeSort.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / algorithms/sorts/GnomeSort GnomeSort.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19 85 | 20 86 | 21 87 | 22 88 | 23  89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |   99 |   100 |   101 |   102 |   103 |   104 |   105 |   106 |   107 |   108 |   109 |   110 |  
/**
111 |  * @function: GnomeSort
112 |  * @description: Ordena un arreglo de números de menor a mayor utilizando el algoritmo Gnome Sort
113 |  * @param: (number[])
114 |  * @return: (number[]) Array ya ordenado
115 |  */
116 |  
117 | export const gnomeSort = (arr: number[]): number[] => {
118 |   Iif (arr.length <= 1) {
119 |     return arr;
120 |   }
121 |   let i: number = 1;
122 |   while (i < arr.length) {
123 |     if (arr[i - 1] <= arr[i]) {
124 |       i++; // Incrementamos el indice de laposicion si la submatriz [i-1;i] ya esta ordenado
125 |     } else {
126 |       [arr[i], arr[i - 1]] = [arr[i - 1], arr[i]];
127 |       i = Math.max(1, i - 1); // devolvernos al indice anterior para comprobar el intercambio
128 |     }
129 |   }
130 |   return arr;
131 | };
132 |  
133 | 134 |
135 |
136 | 141 | 142 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/sorts/GnomeSort/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/sorts/GnomeSort 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/sorts/GnomeSort

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
GnomeSort.ts 84 |
85 |
0%0/110%0/30%0/10%0/10
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/sorts/QuickSort/QuickSort.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/sorts/QuickSort/QuickSort.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / algorithms/sorts/QuickSort QuickSort.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19 85 | 20 86 | 21 87 | 22 88 | 23 89 | 24 90 | 25 91 | 26 92 | 27 93 | 28 94 | 29 95 | 30 96 | 31 97 | 32 98 | 33 99 | 34 100 | 35 101 | 36 102 | 37 103 | 38 104 | 39 105 | 40 106 | 41 107 | 42 108 | 43 109 | 44 110 | 45 111 | 46 112 | 47 113 | 48 114 | 49 115 | 50 116 | 51 117 | 52 118 | 53 119 | 54  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 |   158 |   159 |   160 |   161 |   162 |   163 |   164 |   165 |   166 |   167 |   168 |   169 |   170 |   171 |   172 |  
/**
173 |  * @function QuickSort
174 |  * @description: El algoritmo Quicksort es un algoritmo de ordenamiento muy utilizado y eficiente. Funciona dividiendo el arreglo en dos subarreglos y colocando el elemento pivot en su posición correcta en el arreglo ordenado. Luego, se llama recursivamente a sí mismo para ordenar cada uno de los subarreglos.
175 |  * @param: array {number[]} - Arreglo de numeros a ordenar
176 |  * @param: left {number} - Indice izquierdo del arreglo
177 |  * @param: right {number} - Indice derecho del arreglo
178 |  * @return: {number[]} - Arreglo ordenado
179 |  */
180 |  
181 | export const QuickSort = (
182 |   array: number[],
183 |   left: number,
184 |   right: number
185 | ): number[] => {
186 |   let index;
187 |  
188 |   Iif (array.length > 1) {
189 |     index = partition(array, left, right);
190 |  
191 |     Iif (left < index - 1) {
192 |       QuickSort(array, left, index - 1);
193 |     }
194 |  
195 |     Iif (index < right) {
196 |       QuickSort(array, index, right);
197 |     }
198 |   }
199 |  
200 |   return array;
201 | };
202 |  
203 | function partition(array: number[], left: number, right: number): number {
204 |   const pivot = array[Math.floor((right + left) / 2)];
205 |   let i = left;
206 |   let j = right;
207 |  
208 |   while (i <= j) {
209 |     while (array[i] < pivot) {
210 |       i++;
211 |     }
212 |  
213 |     while (array[j] > pivot) {
214 |       j--;
215 |     }
216 |  
217 |     Iif (i <= j) {
218 |       [array[i], array[j]] = [array[j], array[i]];
219 |       i++;
220 |       j--;
221 |     }
222 |   }
223 |   return i;
224 | }
225 |  
226 | 227 |
228 |
229 | 234 | 235 | 240 | 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /coverage/lcov-report/algorithms/sorts/QuickSort/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for algorithms/sorts/QuickSort 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files algorithms/sorts/QuickSort

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
QuickSort.ts 84 |
85 |
0%0/220%0/40%0/20%0/21
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | if ( 67 | document.getElementById('fileSearch') === document.activeElement && 68 | document.activeElement != null 69 | ) { 70 | // if we're currently focused on the search input, we don't want to navigate 71 | return; 72 | } 73 | 74 | switch (event.which) { 75 | case 78: // n 76 | case 74: // j 77 | goToNext(); 78 | break; 79 | case 66: // b 80 | case 75: // k 81 | case 80: // p 82 | goToPrevious(); 83 | break; 84 | } 85 | }; 86 | })(); 87 | window.addEventListener('keydown', jumpToCode); 88 | -------------------------------------------------------------------------------- /coverage/lcov-report/dataStructures/linkedList/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for dataStructures/linkedList 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files dataStructures/linkedList

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
FileStatementsBranchesFunctionsLines
linkedList.ts 84 |
85 |
0%0/260%0/50%0/60%0/26
linkedListNode.ts 99 |
100 |
0%0/40%0/30%0/20%0/4
113 |
114 |
115 |
116 | 121 | 122 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /coverage/lcov-report/dataStructures/linkedList/linkedListNode.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for dataStructures/linkedList/linkedListNode.ts 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files / dataStructures/linkedList linkedListNode.ts

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

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

57 | 63 |
64 |
65 |

 66 | 
1 67 | 2 68 | 3 69 | 4 70 | 5 71 | 6 72 | 7 73 | 8 74 | 9 75 | 10 76 | 11 77 | 12 78 | 13 79 | 14 80 | 15 81 | 16 82 | 17 83 | 18 84 | 19  85 |   86 |   87 |   88 |   89 |   90 |   91 |   92 |   93 |   94 |   95 |   96 |   97 |   98 |   99 |   100 |   101 |   102 |  
export interface ILinkedListNode<T = unknown> {
103 |   value: T;
104 |   next: ILinkedListNode<T> | null;
105 |   toString: (callback: (value: T) => string) => string;
106 | }
107 |  
108 | export class LinkedListNode<T> implements ILinkedListNode<T> {
109 |   value: T;
110 |   next: ILinkedListNode<T> | null;
111 |   constructor(value: T, next: ILinkedListNode<T> | null = null) {
112 |     this.value = value;
113 |     this.next = next;
114 |   }
115 |  
116 |   toString (callback?: (value: T) => string) {
117 |     return callback ? callback(this.value) : `${this.value}`;
118 |   }
119 | }
120 |  
121 | 122 |
123 |
124 | 129 | 130 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /coverage/lcov-report/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/Algorithms-Typescript/86fba1b8cefd37919117bfab8a302ea5196e64d0/coverage/lcov-report/favicon.png -------------------------------------------------------------------------------- /coverage/lcov-report/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for All files 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |
FileStatementsBranchesFunctionsLines
algorithms/Maths/CoPrime 84 |
85 |
0%0/90%0/40%0/20%0/8
algorithms/ciphers/CaesarCipher 99 |
100 |
0%0/150%0/100%0/40%0/14
algorithms/ciphers/MorseCipher 114 |
115 |
0%0/160%0/30%0/20%0/14
algorithms/search/BinarySearch 129 |
130 |
0%0/270%0/200%0/20%0/19
algorithms/search/DoubleLinearSearchRecursion 144 |
145 |
0%0/100%0/100%0/10%0/9
algorithms/sorts/GnomeSort 159 |
160 |
0%0/110%0/30%0/10%0/10
algorithms/sorts/QuickSort 174 |
175 |
0%0/220%0/40%0/20%0/21
dataStructures/linkedList 189 |
190 |
0%0/300%0/80%0/80%0/30
utils 204 |
205 |
0%0/130%0/90%0/90%0/12
218 |
219 |
220 |
221 | 226 | 227 | 232 | 233 | 234 | 235 | 236 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /coverage/lcov-report/sort-arrow-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/Algorithms-Typescript/86fba1b8cefd37919117bfab8a302ea5196e64d0/coverage/lcov-report/sort-arrow-sprite.png -------------------------------------------------------------------------------- /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 | function onFilterInput() { 28 | const searchValue = document.getElementById('fileSearch').value; 29 | const rows = document.getElementsByTagName('tbody')[0].children; 30 | for (let i = 0; i < rows.length; i++) { 31 | const row = rows[i]; 32 | if ( 33 | row.textContent 34 | .toLowerCase() 35 | .includes(searchValue.toLowerCase()) 36 | ) { 37 | row.style.display = ''; 38 | } else { 39 | row.style.display = 'none'; 40 | } 41 | } 42 | } 43 | 44 | // loads the search box 45 | function addSearchBox() { 46 | var template = document.getElementById('filterTemplate'); 47 | var templateClone = template.content.cloneNode(true); 48 | templateClone.getElementById('fileSearch').oninput = onFilterInput; 49 | template.parentElement.appendChild(templateClone); 50 | } 51 | 52 | // loads all columns 53 | function loadColumns() { 54 | var colNodes = getTableHeader().querySelectorAll('th'), 55 | colNode, 56 | cols = [], 57 | col, 58 | i; 59 | 60 | for (i = 0; i < colNodes.length; i += 1) { 61 | colNode = colNodes[i]; 62 | col = { 63 | key: colNode.getAttribute('data-col'), 64 | sortable: !colNode.getAttribute('data-nosort'), 65 | type: colNode.getAttribute('data-type') || 'string' 66 | }; 67 | cols.push(col); 68 | if (col.sortable) { 69 | col.defaultDescSort = col.type === 'number'; 70 | colNode.innerHTML = 71 | colNode.innerHTML + ''; 72 | } 73 | } 74 | return cols; 75 | } 76 | // attaches a data attribute to every tr element with an object 77 | // of data values keyed by column name 78 | function loadRowData(tableRow) { 79 | var tableCols = tableRow.querySelectorAll('td'), 80 | colNode, 81 | col, 82 | data = {}, 83 | i, 84 | val; 85 | for (i = 0; i < tableCols.length; i += 1) { 86 | colNode = tableCols[i]; 87 | col = cols[i]; 88 | val = colNode.getAttribute('data-value'); 89 | if (col.type === 'number') { 90 | val = Number(val); 91 | } 92 | data[col.key] = val; 93 | } 94 | return data; 95 | } 96 | // loads all row data 97 | function loadData() { 98 | var rows = getTableBody().querySelectorAll('tr'), 99 | i; 100 | 101 | for (i = 0; i < rows.length; i += 1) { 102 | rows[i].data = loadRowData(rows[i]); 103 | } 104 | } 105 | // sorts the table using the data for the ith column 106 | function sortByIndex(index, desc) { 107 | var key = cols[index].key, 108 | sorter = function(a, b) { 109 | a = a.data[key]; 110 | b = b.data[key]; 111 | return a < b ? -1 : a > b ? 1 : 0; 112 | }, 113 | finalSorter = sorter, 114 | tableBody = document.querySelector('.coverage-summary tbody'), 115 | rowNodes = tableBody.querySelectorAll('tr'), 116 | rows = [], 117 | i; 118 | 119 | if (desc) { 120 | finalSorter = function(a, b) { 121 | return -1 * sorter(a, b); 122 | }; 123 | } 124 | 125 | for (i = 0; i < rowNodes.length; i += 1) { 126 | rows.push(rowNodes[i]); 127 | tableBody.removeChild(rowNodes[i]); 128 | } 129 | 130 | rows.sort(finalSorter); 131 | 132 | for (i = 0; i < rows.length; i += 1) { 133 | tableBody.appendChild(rows[i]); 134 | } 135 | } 136 | // removes sort indicators for current column being sorted 137 | function removeSortIndicators() { 138 | var col = getNthColumn(currentSort.index), 139 | cls = col.className; 140 | 141 | cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); 142 | col.className = cls; 143 | } 144 | // adds sort indicators for current column being sorted 145 | function addSortIndicators() { 146 | getNthColumn(currentSort.index).className += currentSort.desc 147 | ? ' sorted-desc' 148 | : ' sorted'; 149 | } 150 | // adds event listeners for all sorter widgets 151 | function enableUI() { 152 | var i, 153 | el, 154 | ithSorter = function ithSorter(i) { 155 | var col = cols[i]; 156 | 157 | return function() { 158 | var desc = col.defaultDescSort; 159 | 160 | if (currentSort.index === i) { 161 | desc = !currentSort.desc; 162 | } 163 | sortByIndex(i, desc); 164 | removeSortIndicators(); 165 | currentSort.index = i; 166 | currentSort.desc = desc; 167 | addSortIndicators(); 168 | }; 169 | }; 170 | for (i = 0; i < cols.length; i += 1) { 171 | if (cols[i].sortable) { 172 | // add the click event handler on the th so users 173 | // dont have to click on those tiny arrows 174 | el = getNthColumn(i).querySelector('.sorter').parentElement; 175 | if (el.addEventListener) { 176 | el.addEventListener('click', ithSorter(i)); 177 | } else { 178 | el.attachEvent('onclick', ithSorter(i)); 179 | } 180 | } 181 | } 182 | } 183 | // adds sorting functionality to the UI 184 | return function() { 185 | if (!getTable()) { 186 | return; 187 | } 188 | cols = loadColumns(); 189 | loadData(); 190 | addSearchBox(); 191 | addSortIndicators(); 192 | enableUI(); 193 | }; 194 | })(); 195 | 196 | window.addEventListener('load', addSorting); 197 | -------------------------------------------------------------------------------- /coverage/lcov-report/utils/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Code coverage report for utils 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 |
21 |
22 |

All files utils

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

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

57 | 63 |
64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
FileStatementsBranchesFunctionsLines
Comparator.ts 84 |
85 |
0%0/130%0/90%0/90%0/12
98 |
99 |
100 |
101 | 106 | 107 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /coverage/lcov.info: -------------------------------------------------------------------------------- 1 | TN: 2 | SF:src\algorithms\Maths\CoPrime\CoPrime.ts 3 | FN:20,(anonymous_0) 4 | FN:29,(anonymous_1) 5 | FNF:2 6 | FNH:0 7 | FNDA:0,(anonymous_0) 8 | FNDA:0,(anonymous_1) 9 | DA:20,0 10 | DA:21,0 11 | DA:22,0 12 | DA:24,0 13 | DA:29,0 14 | DA:31,0 15 | DA:32,0 16 | DA:34,0 17 | LF:8 18 | LH:0 19 | BRDA:21,0,0,0 20 | BRDA:31,1,0,0 21 | BRDA:31,2,0,0 22 | BRDA:31,2,1,0 23 | BRF:4 24 | BRH:0 25 | end_of_record 26 | TN: 27 | SF:src\algorithms\ciphers\CaesarCipher\CaesarCipher.ts 28 | FN:11,(anonymous_0) 29 | FN:20,(anonymous_1) 30 | FN:23,(anonymous_2) 31 | FN:32,(anonymous_3) 32 | FNF:4 33 | FNH:0 34 | FNDA:0,(anonymous_0) 35 | FNDA:0,(anonymous_1) 36 | FNDA:0,(anonymous_2) 37 | FNDA:0,(anonymous_3) 38 | DA:11,0 39 | DA:12,0 40 | DA:13,0 41 | DA:16,0 42 | DA:18,0 43 | DA:20,0 44 | DA:22,0 45 | DA:24,0 46 | DA:25,0 47 | DA:27,0 48 | DA:32,0 49 | DA:33,0 50 | DA:34,0 51 | DA:36,0 52 | LF:14 53 | LH:0 54 | BRDA:11,0,0,0 55 | BRDA:12,1,0,0 56 | BRDA:12,2,0,0 57 | BRDA:12,2,1,0 58 | BRDA:12,2,2,0 59 | BRDA:12,2,3,0 60 | BRDA:16,3,0,0 61 | BRDA:16,3,1,0 62 | BRDA:24,4,0,0 63 | BRDA:33,5,0,0 64 | BRF:10 65 | BRH:0 66 | end_of_record 67 | TN: 68 | SF:src\algorithms\ciphers\MorseCipher\MorseCipher.ts 69 | FN:9,(anonymous_0) 70 | FN:58,(anonymous_1) 71 | FNF:2 72 | FNH:0 73 | FNDA:0,(anonymous_0) 74 | FNDA:0,(anonymous_1) 75 | DA:9,0 76 | DA:15,0 77 | DA:56,0 78 | DA:58,0 79 | DA:59,0 80 | DA:62,0 81 | DA:63,0 82 | DA:64,0 83 | DA:65,0 84 | DA:67,0 85 | DA:68,0 86 | DA:70,0 87 | DA:73,0 88 | DA:76,0 89 | LF:14 90 | LH:0 91 | BRDA:62,0,0,0 92 | BRDA:67,1,0,0 93 | BRDA:67,1,1,0 94 | BRF:3 95 | BRH:0 96 | end_of_record 97 | TN: 98 | SF:src\algorithms\search\BinarySearch\BinarySearch.ts 99 | FN:13,(anonymous_0) 100 | FN:39,(anonymous_1) 101 | FNF:2 102 | FNH:0 103 | FNDA:0,(anonymous_0) 104 | FNDA:0,(anonymous_1) 105 | DA:13,0 106 | DA:14,0 107 | DA:17,0 108 | DA:18,0 109 | DA:19,0 110 | DA:22,0 111 | DA:24,0 112 | DA:27,0 113 | DA:28,0 114 | DA:30,0 115 | DA:32,0 116 | DA:35,0 117 | DA:39,0 118 | DA:40,0 119 | DA:43,0 120 | DA:45,0 121 | DA:47,0 122 | DA:48,0 123 | DA:52,0 124 | LF:19 125 | LH:0 126 | BRDA:14,0,0,0 127 | BRDA:22,1,0,0 128 | BRDA:22,2,0,0 129 | BRDA:22,2,1,0 130 | BRDA:24,3,0,0 131 | BRDA:24,3,1,0 132 | BRDA:27,4,0,0 133 | BRDA:27,4,1,0 134 | BRDA:35,5,0,0 135 | BRDA:35,5,1,0 136 | BRDA:39,6,0,0 137 | BRDA:39,7,0,0 138 | BRDA:40,8,0,0 139 | BRDA:43,9,0,0 140 | BRDA:43,10,0,0 141 | BRDA:43,10,1,0 142 | BRDA:47,11,0,0 143 | BRDA:48,12,0,0 144 | BRDA:52,13,0,0 145 | BRDA:52,13,1,0 146 | BRF:20 147 | BRH:0 148 | end_of_record 149 | TN: 150 | SF:src\algorithms\search\DoubleLinearSearchRecursion\DoubleLinearSearchRecursion.ts 151 | FN:12,(anonymous_0) 152 | FNF:1 153 | FNH:0 154 | FNDA:0,(anonymous_0) 155 | DA:12,0 156 | DA:18,0 157 | DA:19,0 158 | DA:20,0 159 | DA:21,0 160 | DA:22,0 161 | DA:23,0 162 | DA:24,0 163 | DA:26,0 164 | LF:9 165 | LH:0 166 | BRDA:15,0,0,0 167 | BRDA:16,1,0,0 168 | BRDA:18,2,0,0 169 | BRDA:18,2,1,0 170 | BRDA:19,3,0,0 171 | BRDA:19,3,1,0 172 | BRDA:21,4,0,0 173 | BRDA:21,4,1,0 174 | BRDA:23,5,0,0 175 | BRDA:23,5,1,0 176 | BRF:10 177 | BRH:0 178 | end_of_record 179 | TN: 180 | SF:src\algorithms\sorts\GnomeSort\GnomeSort.ts 181 | FN:8,(anonymous_0) 182 | FNF:1 183 | FNH:0 184 | FNDA:0,(anonymous_0) 185 | DA:8,0 186 | DA:9,0 187 | DA:10,0 188 | DA:12,0 189 | DA:13,0 190 | DA:14,0 191 | DA:15,0 192 | DA:17,0 193 | DA:18,0 194 | DA:21,0 195 | LF:10 196 | LH:0 197 | BRDA:9,0,0,0 198 | BRDA:14,1,0,0 199 | BRDA:14,1,1,0 200 | BRF:3 201 | BRH:0 202 | end_of_record 203 | TN: 204 | SF:src\algorithms\sorts\QuickSort\QuickSort.ts 205 | FN:10,(anonymous_0) 206 | FN:32,partition 207 | FNF:2 208 | FNH:0 209 | FNDA:0,(anonymous_0) 210 | FNDA:0,partition 211 | DA:10,0 212 | DA:17,0 213 | DA:18,0 214 | DA:20,0 215 | DA:21,0 216 | DA:24,0 217 | DA:25,0 218 | DA:29,0 219 | DA:33,0 220 | DA:34,0 221 | DA:35,0 222 | DA:37,0 223 | DA:38,0 224 | DA:39,0 225 | DA:42,0 226 | DA:43,0 227 | DA:46,0 228 | DA:47,0 229 | DA:48,0 230 | DA:49,0 231 | DA:52,0 232 | LF:21 233 | LH:0 234 | BRDA:17,0,0,0 235 | BRDA:20,1,0,0 236 | BRDA:24,2,0,0 237 | BRDA:46,3,0,0 238 | BRF:4 239 | BRH:0 240 | end_of_record 241 | TN: 242 | SF:src\dataStructures\linkedList\linkedList.ts 243 | FN:6,(anonymous_0) 244 | FN:15,(anonymous_1) 245 | FN:37,(anonymous_2) 246 | FN:51,(anonymous_3) 247 | FN:66,(anonymous_4) 248 | FN:68,(anonymous_5) 249 | FNF:6 250 | FNH:0 251 | FNDA:0,(anonymous_0) 252 | FNDA:0,(anonymous_1) 253 | FNDA:0,(anonymous_2) 254 | FNDA:0,(anonymous_3) 255 | FNDA:0,(anonymous_4) 256 | FNDA:0,(anonymous_5) 257 | DA:1,0 258 | DA:3,0 259 | DA:7,0 260 | DA:8,0 261 | DA:16,0 262 | DA:17,0 263 | DA:18,0 264 | DA:19,0 265 | DA:21,0 266 | DA:24,0 267 | DA:25,0 268 | DA:28,0 269 | DA:30,0 270 | DA:38,0 271 | DA:39,0 272 | DA:41,0 273 | DA:42,0 274 | DA:45,0 275 | DA:52,0 276 | DA:54,0 277 | DA:55,0 278 | DA:56,0 279 | DA:57,0 280 | DA:60,0 281 | DA:67,0 282 | DA:68,0 283 | LF:26 284 | LH:0 285 | BRDA:17,0,0,0 286 | BRDA:17,1,0,0 287 | BRDA:17,1,1,0 288 | BRDA:24,2,0,0 289 | BRDA:41,3,0,0 290 | BRF:5 291 | BRH:0 292 | end_of_record 293 | TN: 294 | SF:src\dataStructures\linkedList\linkedListNode.ts 295 | FN:10,(anonymous_0) 296 | FN:15,(anonymous_1) 297 | FNF:2 298 | FNH:0 299 | FNDA:0,(anonymous_0) 300 | FNDA:0,(anonymous_1) 301 | DA:7,0 302 | DA:11,0 303 | DA:12,0 304 | DA:16,0 305 | LF:4 306 | LH:0 307 | BRDA:10,0,0,0 308 | BRDA:16,1,0,0 309 | BRDA:16,1,1,0 310 | BRF:3 311 | BRH:0 312 | end_of_record 313 | TN: 314 | SF:src\utils\Comparator.ts 315 | FN:8,(anonymous_0) 316 | FN:18,(anonymous_1) 317 | FN:32,(anonymous_2) 318 | FN:42,(anonymous_3) 319 | FN:52,(anonymous_4) 320 | FN:62,(anonymous_5) 321 | FN:72,(anonymous_6) 322 | FN:79,(anonymous_7) 323 | FN:81,(anonymous_8) 324 | FNF:9 325 | FNH:0 326 | FNDA:0,(anonymous_0) 327 | FNDA:0,(anonymous_1) 328 | FNDA:0,(anonymous_2) 329 | FNDA:0,(anonymous_3) 330 | FNDA:0,(anonymous_4) 331 | FNDA:0,(anonymous_5) 332 | FNDA:0,(anonymous_6) 333 | FNDA:0,(anonymous_7) 334 | FNDA:0,(anonymous_8) 335 | DA:2,0 336 | DA:9,0 337 | DA:19,0 338 | DA:20,0 339 | DA:23,0 340 | DA:33,0 341 | DA:43,0 342 | DA:53,0 343 | DA:63,0 344 | DA:73,0 345 | DA:80,0 346 | DA:81,0 347 | LF:12 348 | LH:0 349 | BRDA:9,0,0,0 350 | BRDA:9,0,1,0 351 | BRDA:19,1,0,0 352 | BRDA:23,2,0,0 353 | BRDA:23,2,1,0 354 | BRDA:63,3,0,0 355 | BRDA:63,3,1,0 356 | BRDA:73,4,0,0 357 | BRDA:73,4,1,0 358 | BRF:9 359 | BRH:0 360 | end_of_record 361 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "@jest/types"; 2 | // Sync object 3 | const config: Config.InitialOptions = { 4 | verbose: true, 5 | transform: { 6 | "^.+\\.tsx?$": "ts-jest" 7 | } 8 | }; 9 | export default config; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "algorithms-typescript", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "description": "About Algoritmos y estructuras de datos implementados en Typescript para principiantes, siguiendo las mejores prácticas.", 6 | "main": "", 7 | "license": "MIT", 8 | "author": "Bryan-Herrera-Dev", 9 | "scripts": { 10 | "test": "jest --no-cache", 11 | "test-changed": "jest --onlyChanged", 12 | "lint": "eslint . --ext .ts", 13 | "style": "npm run lint -- --fix", 14 | "prepare": "husky install", 15 | "test-files": "node scripts/ValidateDirectory.mjs" 16 | }, 17 | "dependencies": { 18 | "@types/jest": "^29.2.2", 19 | "globby": "^13.1.3", 20 | "jest": "^29.2.2", 21 | "ts-jest": "^29.0.3", 22 | "ts-node": "^10.9.1", 23 | "typescript": "^4.8.4" 24 | }, 25 | "engines": { 26 | "node": "18.12.1" 27 | }, 28 | "devDependencies": { 29 | "@typescript-eslint/eslint-plugin": "^5.42.1", 30 | "@typescript-eslint/parser": "^5.42.1", 31 | "babel-jest": "^29.2.2", 32 | "eslint": "^8.27.0", 33 | "husky": "^8.0.2" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /public/TS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bryan-Herrera-DEV/Algorithms-Typescript/86fba1b8cefd37919117bfab8a302ea5196e64d0/public/TS.png -------------------------------------------------------------------------------- /scripts/ValidateDirectory.mjs: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import { globby } from "globby"; 3 | 4 | 5 | function validateFolderSpecialCharacters(filePath, fileName) { 6 | // check for special characters with regex 7 | const regex = new RegExp(/[^a-zA-Z]/); 8 | if (regex.test(filePath)) { 9 | throw new Error( 10 | `Folder name '${filePath}' contains special characters. Please remove them.` 11 | ); 12 | } 13 | if (regex.test(fileName)) { 14 | throw new Error( 15 | `File name '${fileName}' contains special characters. Please remove them.` 16 | ); 17 | } 18 | } 19 | 20 | function validateFolderAndFileNames(filePath, fileName) { 21 | if (filePath === "src") { 22 | throw new Error("Folder name cannot be 'src'"); 23 | } 24 | if (fileName.toLowerCase() !== filePath.toLowerCase()) { 25 | throw new Error( 26 | `Folder name '${filePath}' does not match file name '${fileName}'` 27 | ); 28 | } 29 | } 30 | 31 | function pathsToMarkdown(filePaths) { 32 | for (let filepath of filePaths) { 33 | let filename = path.basename(filepath).split(".")[0]; 34 | filepath = path.dirname(filepath); 35 | filepath = filepath.replace("src/algorithms/", ""); 36 | filepath = filepath.split("/")[1]; 37 | 38 | validateFolderSpecialCharacters(filepath, filename); 39 | validateFolderAndFileNames(filepath, filename); 40 | } 41 | return filePaths; 42 | } 43 | 44 | // get paths of all .ts files - excluding node_modules, the .github folder, tests and config stuff 45 | globby([ 46 | "src/algorithms/**/*.ts", 47 | "!(node_modules|.github)/**/*", 48 | "!**/__test__/**/*", 49 | "!**/*.test.ts", 50 | "!*.config.ts", 51 | ]) 52 | // create markdown content 53 | .then(pathsToMarkdown); 54 | -------------------------------------------------------------------------------- /src/algorithms/Maths/CoPrime/CoPrime.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function CoPrime 3 | * @description Es un algoritmo matemático que nos permite validar si los factores primos de dos números tienen un factor común entre si, el cual es el 1. 4 | * Tambien se le conoce como 'Primos Relativos' y podemos hallarlo con sus factores primos o con su MCD. 5 | * @param: {number} firstNumber - Primer número a comparar. 6 | * @param: {number} secondNumber - Segundo número a comparar. 7 | * @return: {boolean} - Devuelve true si los números son 'Co-Primos', false en caso contrario. 8 | */ 9 | 10 | // Aqui haremos uso del Algoritmos Euclides para encontrar el MCD (Máximo común divisor) de dos números. 11 | // Explicacion 12 | /* 13 | | Q | A | B | R | 14 | | 2 | 33 | 12 | 9 | Resto de (12 / 33) = 9 15 | | 1 | 12 | 9 | 3 | Resto de (9 / 12 ) = 3 16 | | 3 | 9 | 3 | 0 | Resto de (3 / 9 ) = 0 17 | | x | 3 | 0 | x | Cuando B = 0 sabemos que el MCD es A 18 | */ 19 | 20 | const EuclideanMCD = (a: number, b: number): number => { 21 | if (b === 0) { 22 | return a; 23 | } // validamos si B es igual que 0 y devolvemos A 24 | return EuclideanMCD(b, a % b); // vamos a usar retornar la misma funcion hasta que se cumpla la valdiacion previa, uso de recursividad 25 | }; 26 | 27 | 28 | // La manera en la que lo hallaremos es con el algoritmo de Euclides y validar su resultado con el 1, si es igual a 1 entonces son 'Co-Primos' 29 | export const CoPrime = (firstNumber: number, secondNumber: number): boolean | TypeError => { 30 | // Validamos que ambos parametros sean numeros 31 | if (typeof firstNumber !== "number" || typeof secondNumber !== "number") { 32 | return new TypeError("Argument is not a number."); 33 | } 34 | return EuclideanMCD(firstNumber, secondNumber) === 1; 35 | }; 36 | -------------------------------------------------------------------------------- /src/algorithms/Maths/CoPrime/__tests__/CoPrime.test.ts: -------------------------------------------------------------------------------- 1 | import { CoPrime } from "../CoPrime"; 2 | 3 | describe("Probando algoritmo 'Co-Prime'", () => { 4 | it("Tiene que estar definido", () => { 5 | expect(CoPrime(2, 3)).toBeDefined(); 6 | }); 7 | it("Tiene que devolver un booleano", () => { 8 | expect(typeof CoPrime(2, 3)).toBe("boolean"); 9 | }); 10 | it("Tiene que devolver true si los números son 'Co-Primos'", () => { 11 | expect(CoPrime(15, 28)).toBe(true); 12 | }); 13 | it("Tiene que devolver false si los números no son 'Co-Primos'", () => { 14 | expect(CoPrime(15, 20)).toBe(false); 15 | }); 16 | }); -------------------------------------------------------------------------------- /src/algorithms/Maths/EulerTotient/__tests__/CoPrime.test.ts: -------------------------------------------------------------------------------- 1 | import { eulerTotient } from "../eulerTotient"; 2 | 3 | describe("Probando algoritmo 'Totiente de Euler'", () => { 4 | test("PHI de 36 debe ser 12", () => { 5 | expect(eulerTotient(36)).toBe(12); 6 | }); 7 | test("PHI de 97 (numero primo) debe ser 96", () => { 8 | expect(eulerTotient(36)).toBe(12); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/algorithms/Maths/EulerTotient/eulerTotient.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function EulerTotient 3 | * @description es una función que cuenta la cantidad de números hasta n que son coprimos con n 4 | * @param: {number} n - Numero primo 5 | * @return: {number} - Devuelve cuantos numeros menores o iguales a n son coprimos de n 6 | */ 7 | 8 | const primeFactors = (n: number): number[] => { 9 | const factors: Set = new Set(); // set para almacenar los factores unicos 10 | for (let i = 2; i * i <= n; i++) { 11 | while (n % i === 0) { 12 | factors.add(i); 13 | n /= i; 14 | } 15 | } 16 | if (n > 1) { 17 | factors.add(n); 18 | } 19 | return Array.from(factors); 20 | }; 21 | 22 | const product = (numbers: number[]) => numbers.reduce((acc, val) => acc * val, 1); 23 | 24 | export const eulerTotient = (n: number): number => { 25 | const factors = primeFactors(n); 26 | const factorsAdjustment = factors.map(factor => (1 - 1 / factor)); 27 | return Math.floor(n * product(factorsAdjustment)); 28 | }; 29 | -------------------------------------------------------------------------------- /src/algorithms/ciphers/CaesarCipher/CaesarCipher.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function CaesarCipher 3 | * @description: En criptografía, el cifrado César, también conocido como cifrado del César, cifrado por desplazamiento. Es un tipo de cifrado por sustitución en el que cada letra del texto plano se sustituye por una letra en un número fijo de posiciones hacia abajo del alfabeto. Por ejemplo, con un desplazamiento a la izquierda de 3, la D sería sustituida por la A, la E se convertiría en la B, y así sucesivamente. 4 | * @param: str {string} - Cadena a encriptar o a desencriptar 5 | * @param: rotation {number} - Numero que va a definir el desplazamiento del texto 6 | * @param: encrypt {boolean} - Si es true, encriptamos, si es false, desencriptamos 7 | * @return: {string} - cadena desencriptada i encriptada dependiendo el caso 8 | */ 9 | 10 | 11 | export const CaesarCipher = (str: string, rotation: number, encrypt: boolean = true): string => { 12 | if (typeof str !== "string" || !Number.isInteger(rotation) || rotation <= 0 || typeof encrypt !== "boolean") { 13 | throw new TypeError("Argumentos invalidos"); 14 | } 15 | 16 | rotation = encrypt ? rotation : -(rotation); 17 | 18 | const alphabets = new Array(26) 19 | .fill(0) 20 | .map((_ :string, index: number) => String.fromCharCode(97 + index)); 21 | 22 | const cipherMap = alphabets.reduce( 23 | (map, char, index) => { 24 | if (((rotation + index) % 26) < 0) { 25 | return map.set(char, alphabets[26 + ((rotation + index) % 26)]); 26 | } 27 | return map.set(char, alphabets[(rotation + index) % 26]); 28 | }, 29 | new Map() 30 | ); 31 | 32 | return str.replace(/[a-z]/gi, (char: string): string => { 33 | if (/[A-Z]/.test(char)) { 34 | return cipherMap.get(char.toLocaleLowerCase()).toUpperCase(); 35 | } 36 | return cipherMap.get(char); 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /src/algorithms/ciphers/CaesarCipher/__tests__/CaesarCipher.test.ts: -------------------------------------------------------------------------------- 1 | import { CaesarCipher } from "../CaesarCipher"; 2 | 3 | describe("Probando el algoritmo de Crifrado 'Caeser Cipher'", () => { 4 | it("1. Probando casos de error controlados", () => { 5 | expect(() => CaesarCipher(false as unknown as string, 2)).toThrow(); // .toThrow espera errores controlados de tipo 'throw new Error' 6 | expect(() => CaesarCipher(0 as unknown as string, "error" as unknown as number)).toThrow(); // .toThrow espera errores controlados de tipo 'throw new Error' 7 | }); 8 | 9 | it("2. Probando casos de encriptado", () => { 10 | expect(CaesarCipher("abcd", 1)).toBe("bcde"); 11 | expect(CaesarCipher("ABC", 2)).toBe("CDE"); 12 | }); 13 | 14 | it("3. Probando casos de des-encriptado", () => { 15 | expect(CaesarCipher("bcde", 1, false)).toBe("abcd"); 16 | expect(CaesarCipher("CDE", 2, false)).toBe("ABC"); 17 | expect(CaesarCipher("ab", 2, false)).toBe("yz"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/algorithms/ciphers/MorseCipher/MorseCipher.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function MorseCipher 3 | * @description Es un algoritmo de cifrado que usa una serie de puntos y rayas para representar cada letra del alfabeto. 4 | * @param: {string} text - Texto a cifrar. 5 | * @param: {string} action - Accion a realizar, cifrar o descifrar. 6 | * @return: {string} - Devuelve el texto cifrado o descifrado. 7 | */ 8 | 9 | export const morseCipher = ( 10 | str: string, 11 | action: "cipher" | "des-cipher" 12 | ): string => { 13 | const toMorse: { 14 | [key: string]: string; 15 | } = { 16 | a: ".-", 17 | b: "-...", 18 | c: "-.-.", 19 | d: "-..", 20 | e: ".", 21 | f: "..-.", 22 | g: "--.", 23 | h: "....", 24 | i: "..", 25 | j: ".---", 26 | k: "-.-", 27 | l: ".-..", 28 | m: "--", 29 | n: "-.", 30 | o: "---", 31 | p: ".--.", 32 | q: "--.-", 33 | r: ".-.", 34 | s: "...", 35 | t: "-", 36 | u: "..-", 37 | v: "...-", 38 | w: ".--", 39 | x: "-..-", 40 | y: "-.--", 41 | z: "--..", 42 | "0": "-----", 43 | "1": ".----", 44 | "2": "..---", 45 | "3": "...--", 46 | "4": "....-", 47 | "5": ".....", 48 | "6": "-....", 49 | "7": "--...", 50 | "8": "---..", 51 | "9": "----.", 52 | }; 53 | 54 | const toText: { 55 | [key: string]: string; 56 | } = {}; 57 | 58 | Object.keys(toMorse).forEach((key: string) => { 59 | toText[toMorse[key]] = key; 60 | }); 61 | 62 | if (action === "cipher") { 63 | let result = ""; 64 | for (let i = 0; i < str.length; i++) { 65 | const letter = str[i].toLocaleLowerCase(); 66 | 67 | if (toMorse[letter]) { 68 | result += toMorse[letter] + " "; 69 | } else { 70 | result += " "; 71 | } 72 | } 73 | return result.trim(); 74 | } 75 | 76 | return toMorse.saludo; 77 | }; 78 | -------------------------------------------------------------------------------- /src/algorithms/ciphers/MorseCipher/__tests__/MorseCipher.test.ts: -------------------------------------------------------------------------------- 1 | import { morseCipher } from "../MorseCipher"; 2 | 3 | describe("Probando el Cifrador: Morse Cipher", () => { 4 | it("Tiene que devolver un texto Encriptado/Cifrado", () => { 5 | expect(morseCipher("hello world", "cipher")).toBe( 6 | ".... . .-.. .-.. --- .-- --- .-. .-.. -.." 7 | ); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/algorithms/search/BinarySearch/BinarySearch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function BinarySearch 3 | * @description algoritmo de búsqueda binaria (implementaciones iterativas y recursivas) para una matriz ordenada. 4 | * El algoritmo busca un valor específico en una matriz ordenada en tiempo logarítmico. 5 | * Repetidamente divide por la mitad la porción de la lista que podría contener el ítem, 6 | * hasta que ha reducido los posibles índices a sólo uno. 7 | * 8 | * @param: {number[]} array - Lista ordenada de numeros 9 | * @param: {number} target - Numero a buscar 10 | * @return: {number} - índice del número de destino en la lista, o -1 si no se encuentra 11 | */ 12 | 13 | export const binarySearchIterative = (array: number[], target: number): number => { 14 | if (array.length === 0) {return -1;} 15 | 16 | // declarar punteros para los índices de inicio, medio y final 17 | let start = 0, 18 | end = array.length - 1, 19 | middle = (start + end) >> 1; 20 | 21 | // asegúrese de que el objetivo está dentro de los límites de la matriz 22 | if (target < array[start] || target > array[end]) {return -1;} 23 | 24 | while (array[middle] !== target && start <= end) { 25 | // si el objetivo es menor que el valor medio, mueve el puntero final para que sea medio -1 para reducir el espacio de búsqueda 26 | // en caso contrario, mueve el puntero de inicio para que sea medio + 1 27 | if (target < array[middle]) 28 | {end = middle - 1;} 29 | else 30 | {start = middle + 1;} 31 | // volver a declarar el índice medio cuando la ventana de búsqueda cambia 32 | middle = (start + end) >> 1; 33 | } 34 | // devuelve el índice medio si es igual al objetivo 35 | return array[middle] === target ? middle : -1; 36 | }; 37 | 38 | 39 | export const binarySearchRecursive = (array: number[], target: number, start = 0, end = array.length - 1): number => { 40 | if (array.length === 0) {return -1;} 41 | 42 | // asegúrese de que el objetivo está dentro de los límites de la matriz 43 | if (target < array[start] || target > array[end]) {return -1;} 44 | 45 | const middle = (start + end) >> 1; 46 | 47 | if (array[middle] === target) {return middle;} // número encontrado 48 | if (start > end) {return -1;} // número no encontrado 49 | 50 | // si el objetivo es menor que el valor medio, mueve el puntero final para que sea medio -1 para reducir el espacio de búsqueda 51 | // en caso contrario, mueve el puntero de inicio para que sea medio + 1 52 | return target < array[middle] 53 | ? binarySearchRecursive(array, target, start, middle - 1) 54 | : binarySearchRecursive(array, target, middle + 1, end); 55 | }; 56 | -------------------------------------------------------------------------------- /src/algorithms/search/BinarySearch/__tests__/BinarySearch.test.ts: -------------------------------------------------------------------------------- 1 | import { binarySearchIterative, binarySearchRecursive } from "../BinarySearch"; 2 | 3 | describe("Probando algoritmo 'BinarySearch'", () => { 4 | const testArray: number[] = [1, 2, 3, 4]; 5 | type FunctionsArray = { (array: number[], index: number): number }[]; 6 | const functions: FunctionsArray = [binarySearchIterative, binarySearchRecursive]; 7 | 8 | for (const func of functions) { 9 | it("Tiene que estar definido", () => { 10 | expect(func(testArray, 2)).toBeDefined(); 11 | }); 12 | it("Tiene que devolver un numero", () => { 13 | expect(typeof func(testArray, 2)).toBe("number"); 14 | }); 15 | it("Tiene que devolver -1 si el target no se encuentra en el array", () => { 16 | expect(func(testArray, 5)).toBe(-1); 17 | }); 18 | it("Tiene que devolver -1 si no hay elementos en el array", () => { 19 | expect(func([], 5)).toBe(-1); 20 | }); 21 | it("Tiene que devolver el índice del target si se encuentra en el array", () => { 22 | expect(func(testArray, 2)).toBe(1); 23 | }); 24 | it("Tiene que devolver un índice correcto de destino cuando el array contiene valores duplicados", () => { 25 | expect(func([1, 2, 2, 3, 3, 3, 4], 2)).toBe(1); 26 | }); 27 | it("Tiene que devolver el primer índice cuando el objetivo es el primer elemento del array", () => { 28 | expect(func(testArray, 1)).toBe(0); 29 | }); 30 | it("Tiene que devolver el último índice cuando el objetivo es el último elemento del array", () => { 31 | expect(func(testArray, 4)).toBe(3); 32 | }); 33 | } 34 | }); 35 | -------------------------------------------------------------------------------- /src/algorithms/search/DoubleLinearSearchRecursion/DoubleLinearSearchRecursion.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function DoubleLinearSearchRecursion 3 | * @description Una ligera mejora con respecto a la típica búsqueda lineal. 4 | * 5 | * @param: {number[]} list_data - la lista que se va a buscar 6 | * @param: {number} clave - la clave a buscar 7 | * @param: {number} left - índice del primer elemento 8 | * @param: {number} right - el índice del último elemento 9 | * @return: {number} - el índice del valor de la clave si se encuentra, -1 en caso contrario. 10 | */ 11 | 12 | export const DoubleLinearSearchRecursion = ( 13 | list_data: number[], 14 | clave: number, 15 | left: number = 0, 16 | right: number = 0 17 | ): number => { 18 | right = right || list_data.length - 1; 19 | if (left > right) { 20 | return -1; 21 | } else if (list_data[left] === clave) { 22 | return left; 23 | } else if (list_data[right] === clave) { 24 | return right; 25 | } else { 26 | return DoubleLinearSearchRecursion(list_data, clave, left + 1, right - 1); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/algorithms/search/DoubleLinearSearchRecursion/__tests__/DoubleLinearSearchRecursion.test.ts: -------------------------------------------------------------------------------- 1 | import { DoubleLinearSearchRecursion } from "../DoubleLinearSearchRecursion"; 2 | 3 | describe("Probando algoritmo 'Duble Linear Search With Recursion'", () => { 4 | const testArray: number[] = [1, 2, 3, 4]; 5 | 6 | it("Tiene que estar definido", () => { 7 | expect(DoubleLinearSearchRecursion(testArray, 2)).toBeDefined(); 8 | }); 9 | it("Tiene que devolver un numero", () => { 10 | expect(typeof DoubleLinearSearchRecursion(testArray, 2)).toBe("number"); 11 | }); 12 | it("Tiene que devolver -1 si el target no se encuentra en el array", () => { 13 | expect(DoubleLinearSearchRecursion(testArray, 5)).toBe(-1); 14 | }); 15 | it("Tiene que devolver -1 si no hay elementos en el array", () => { 16 | expect(DoubleLinearSearchRecursion([], 5)).toBe(-1); 17 | }); 18 | it("Tiene que devolver el índice del target si se encuentra en el array", () => { 19 | expect(DoubleLinearSearchRecursion(testArray, 2)).toBe(1); 20 | }); 21 | it("Tiene que devolver un índice correcto de destino cuando el array contiene valores duplicados", () => { 22 | expect(DoubleLinearSearchRecursion([1, 2, 2, 3, 3, 3, 4], 2)).toBe(1); 23 | }); 24 | it("Tiene que devolver el primer índice cuando el objetivo es el primer elemento del array", () => { 25 | expect(DoubleLinearSearchRecursion(testArray, 1)).toBe(0); 26 | }); 27 | it("Tiene que devolver el último índice cuando el objetivo es el último elemento del array", () => { 28 | expect(DoubleLinearSearchRecursion(testArray, 4)).toBe(3); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /src/algorithms/sorts/GnomeSort/GnomeSort.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function: GnomeSort 3 | * @description: Ordena un arreglo de números de menor a mayor utilizando el algoritmo Gnome Sort 4 | * @param: (number[]) 5 | * @return: (number[]) Array ya ordenado 6 | */ 7 | 8 | export const gnomeSort = (arr: number[]): number[] => { 9 | if (arr.length <= 1) { 10 | return arr; 11 | } 12 | let i: number = 1; 13 | while (i < arr.length) { 14 | if (arr[i - 1] <= arr[i]) { 15 | i++; // Incrementamos el indice de laposicion si la submatriz [i-1;i] ya esta ordenado 16 | } else { 17 | [arr[i], arr[i - 1]] = [arr[i - 1], arr[i]]; 18 | i = Math.max(1, i - 1); // devolvernos al indice anterior para comprobar el intercambio 19 | } 20 | } 21 | return arr; 22 | }; 23 | -------------------------------------------------------------------------------- /src/algorithms/sorts/GnomeSort/__tests__/GnomeSort.test.ts: -------------------------------------------------------------------------------- 1 | import { gnomeSort } from "../GnomeSort"; 2 | 3 | describe("Probando algoritmo 'Gnome Sort'", () => { 4 | const testsCases: number[][] = [ 5 | [], 6 | [2, 1], 7 | [3, 2, 1], 8 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 9 | [8, 5, 6, 9, 7, 2, 1, 1, 8, 10, 6] 10 | ]; 11 | test.each(testsCases)( 12 | "Deeberia devolver el valor correcto del caso de prueba: %#", 13 | (...arr: number[]) => { 14 | expect(gnomeSort([...arr])).toStrictEqual( 15 | [...arr].sort((a: number, b: number) => a - b) 16 | ); 17 | } 18 | ); 19 | }); 20 | -------------------------------------------------------------------------------- /src/algorithms/sorts/QuickSort/QuickSort.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @function QuickSort 3 | * @description: El algoritmo Quicksort es un algoritmo de ordenamiento muy utilizado y eficiente. Funciona dividiendo el arreglo en dos subarreglos y colocando el elemento pivot en su posición correcta en el arreglo ordenado. Luego, se llama recursivamente a sí mismo para ordenar cada uno de los subarreglos. 4 | * @param: array {number[]} - Arreglo de numeros a ordenar 5 | * @param: left {number} - Indice izquierdo del arreglo 6 | * @param: right {number} - Indice derecho del arreglo 7 | * @return: {number[]} - Arreglo ordenado 8 | */ 9 | 10 | export const QuickSort = ( 11 | array: number[], 12 | left: number, 13 | right: number 14 | ): number[] => { 15 | let index; 16 | 17 | if (array.length > 1) { 18 | index = partition(array, left, right); 19 | 20 | if (left < index - 1) { 21 | QuickSort(array, left, index - 1); 22 | } 23 | 24 | if (index < right) { 25 | QuickSort(array, index, right); 26 | } 27 | } 28 | 29 | return array; 30 | }; 31 | 32 | function partition(array: number[], left: number, right: number): number { 33 | const pivot = array[Math.floor((right + left) / 2)]; 34 | let i = left; 35 | let j = right; 36 | 37 | while (i <= j) { 38 | while (array[i] < pivot) { 39 | i++; 40 | } 41 | 42 | while (array[j] > pivot) { 43 | j--; 44 | } 45 | 46 | if (i <= j) { 47 | [array[i], array[j]] = [array[j], array[i]]; 48 | i++; 49 | j--; 50 | } 51 | } 52 | return i; 53 | } 54 | -------------------------------------------------------------------------------- /src/algorithms/sorts/QuickSort/__tests__/QuickSort.test.ts: -------------------------------------------------------------------------------- 1 | import { QuickSort } from "../QuickSort"; 2 | 3 | describe("Probando algoritmo 'Quick Sort'", () => { 4 | const testsCases: number[][] = [ 5 | [], 6 | [2, 1], 7 | [3, 2, 1], 8 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 9 | [8, 5, 6, 9, 7, 2, 1, 1, 8, 10, 6] 10 | ]; 11 | test.each(testsCases)( 12 | "Deeberia devolver el valor correcto del caso de prueba: %#", 13 | (...arr: number[]) => { 14 | expect(QuickSort([...arr], 0, arr.length - 1)).toStrictEqual( 15 | [...arr].sort((a: number, b: number) => a - b) 16 | ); 17 | } 18 | ); 19 | }); 20 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/__tests__/linkedList.test.ts: -------------------------------------------------------------------------------- 1 | import { LinkedList } from "../linkedList"; 2 | 3 | describe("Probando Estructura de datos: Linked-List", () => { 4 | it("Debe crear una lista enlazada vacia", () => { 5 | const linkedList = new LinkedList(); 6 | 7 | expect(linkedList.head).toBeNull(); 8 | expect(linkedList.tail).toBeNull(); 9 | }); 10 | 11 | it("Debe agregar un nodo a la lista enlazada", () => { 12 | const linkedList = new LinkedList(); 13 | 14 | linkedList.append(1); 15 | 16 | expect(linkedList.head?.value).toBe(1); 17 | expect(linkedList.tail?.value).toBe(1); 18 | }); 19 | it("Debe agregar dos nodo a la lista enlazada", () => { 20 | const linkedList = new LinkedList(); 21 | 22 | linkedList.append(1); 23 | linkedList.append(2); 24 | 25 | expect(linkedList.head?.value).toBe(1); 26 | expect(linkedList.tail?.value).toBe(2); 27 | }); 28 | it("Debe agregar un nodo y luego agregar otro nodo pero al inicio de la lista", () => { 29 | const linkedList = new LinkedList(); 30 | 31 | linkedList.append(1); 32 | linkedList.prepend(2); 33 | 34 | expect(linkedList.head?.value).toBe(2); 35 | expect(linkedList.tail?.value).toBe(1); 36 | }); 37 | 38 | it("Debe agregar dos nodo a la lista enlazada y luego testear el metodo toString", () => { 39 | const linkedList = new LinkedList(); 40 | 41 | linkedList.append(1); 42 | linkedList.append(2); 43 | linkedList.append(3); 44 | linkedList.append(4); 45 | 46 | expect(linkedList.toString()).toBe("1,2,3,4"); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/__tests__/linkedListNode.test.ts: -------------------------------------------------------------------------------- 1 | import { LinkedListNode } from "../linkedListNode"; 2 | export interface ILinkedListNode { 3 | value: Values; 4 | next: null; 5 | } 6 | describe("LinkedListNode", () => { 7 | it("Debe crear un nodo de lista con el valor", () => { 8 | const node = new LinkedListNode(1); 9 | 10 | expect(node.value).toBe(1); 11 | expect(node.next).toBeNull(); 12 | }); 13 | 14 | it("Debe crear un nodo de lista con un objeto como valor", () => { 15 | const nodeValue = { value: 1, key: "test" }; 16 | const nodeList = new LinkedListNode<{ 17 | value: number; 18 | key: string; 19 | }>(nodeValue); 20 | 21 | expect(nodeList.value.value).toBe(1); 22 | expect(nodeList.value.key).toBe("test"); 23 | expect(nodeList.next).toBeNull(); 24 | }); 25 | 26 | it("Debe enlazar los nodos entre si", () => { 27 | const node2 = new LinkedListNode(2); 28 | const node1 = new LinkedListNode(1, node2); 29 | 30 | expect(node1.next).toBeDefined(); 31 | expect(node2.next).toBeNull(); 32 | expect(node1.value).toBe(1); 33 | expect(node1.next?.value).toBe(2); 34 | }); 35 | it("Debe convertir el nodo en cadena", () => { 36 | const node = new LinkedListNode(1); 37 | 38 | expect(node.toString()).toBe("1"); 39 | 40 | node.value = "string value"; 41 | expect(node.toString()).toBe("string value"); 42 | }); 43 | 44 | it("Debe convertir el nodo en cadena con un 'stringifier' personalizado", () => { 45 | const nodeValue = { value: 1, key: "test" }; 46 | const node = new LinkedListNode<{ 47 | value: number; 48 | key: string; 49 | }>(nodeValue); 50 | const toStringCallback = (value: { value: number; key: string }): string => `value: ${value.value}, key: ${value.key}`; 51 | 52 | expect(node.toString(toStringCallback)).toBe("value: 1, key: test"); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/linkedList.ts: -------------------------------------------------------------------------------- 1 | import { ILinkedListNode, LinkedListNode } from "./linkedListNode"; 2 | 3 | export class LinkedList { 4 | head: ILinkedListNode | null; 5 | tail: ILinkedListNode | null; 6 | constructor() { 7 | this.head = null; 8 | this.tail = null; 9 | } 10 | 11 | /** 12 | * @param {*} value 13 | * @return {LinkedList} 14 | */ 15 | append(value: T) { 16 | const newNode = new LinkedListNode(value); 17 | if (!this.head && !this.tail) { 18 | this.head = newNode; 19 | this.tail = newNode; 20 | 21 | return this; 22 | } 23 | 24 | if (this.tail) { 25 | this.tail.next = newNode; 26 | } 27 | 28 | this.tail = newNode; 29 | 30 | return this; 31 | } 32 | 33 | /** 34 | * @param {*} value 35 | * @return {LinkedList} 36 | */ 37 | prepend(value: T) { 38 | const newNode = new LinkedListNode(value, this.head); 39 | this.head = newNode; 40 | 41 | if (!this.tail) { 42 | this.tail = newNode; 43 | } 44 | 45 | return this; 46 | } 47 | 48 | /** 49 | * @return {LinkedList[]} 50 | */ 51 | toArray(): LinkedListNode[] { 52 | const nodes = []; 53 | 54 | let currentNode = this.head; 55 | while (currentNode) { 56 | nodes.push(currentNode); 57 | currentNode = currentNode.next; 58 | } 59 | 60 | return nodes; 61 | } 62 | 63 | /** 64 | * @returns {string} 65 | */ 66 | toString(callback?: (value: unknown) => string): string { 67 | return this.toArray() 68 | .map((node) => node.toString(callback)) 69 | .toString(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/linkedListNode.ts: -------------------------------------------------------------------------------- 1 | export interface ILinkedListNode { 2 | value: T; 3 | next: ILinkedListNode | null; 4 | toString: (callback: (value: T) => string) => string; 5 | } 6 | 7 | export class LinkedListNode implements ILinkedListNode { 8 | value: T; 9 | next: ILinkedListNode | null; 10 | constructor(value: T, next: ILinkedListNode | null = null) { 11 | this.value = value; 12 | this.next = next; 13 | } 14 | 15 | toString (callback?: (value: T) => string) { 16 | return callback ? callback(this.value) : `${this.value}`; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/Comparator.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | export default class Comparator { 3 | compare: (a: any, b: any) => 0 | 1 | -1; 4 | /** 5 | * Constructor. 6 | * @param {function(a: *, b: *)} [compareFunction] - Puede ser función de comparación personalizada que, vamos a 7 | */ 8 | constructor(compareFunction: (a: any, b: any) => 0 | 1 | -1) { 9 | this.compare = compareFunction || Comparator.defaultCompareFunction; 10 | } 11 | 12 | /** 13 | * Función de comparación por defecto. Sólo asume que "a" y "b" son cadenas o números. 14 | * @param {(string|number)} a 15 | * @param {(string|number)} b 16 | * @returns {number} 17 | */ 18 | static defaultCompareFunction(a: number, b: number) { 19 | if (a === b) { 20 | return 0; 21 | } 22 | 23 | return a < b ? -1 : 1; 24 | } 25 | 26 | /** 27 | * Comprueba si dos variables son iguales. 28 | * @param {*} a 29 | * @param {*} b 30 | * @return {boolean} 31 | */ 32 | equal(a: any, b: any) { 33 | return this.compare(a, b) === 0; 34 | } 35 | 36 | /** 37 | * Comprueba si la variable "a" es menor que "b". 38 | * @param {*} a 39 | * @param {*} b 40 | * @return {boolean} 41 | */ 42 | lessThan(a: any, b: any) { 43 | return this.compare(a, b) < 0; 44 | } 45 | 46 | /** 47 | * Comprueba si la variable "a" es mayor que "b". 48 | * @param {*} a 49 | * @param {*} b 50 | * @return {boolean} 51 | */ 52 | greaterThan(a: any, b: any) { 53 | return this.compare(a, b) > 0; 54 | } 55 | 56 | /** 57 | * Comprueba si la variable "a" es menor o igual que "b". 58 | * @param {*} a 59 | * @param {*} b 60 | * @return {boolean} 61 | */ 62 | lessThanOrEqual(a: any, b: any) { 63 | return this.lessThan(a, b) || this.equal(a, b); 64 | } 65 | 66 | /** 67 | * Comprueba si la variable "a" es mayor o igual que "b". 68 | * @param {*} a 69 | * @param {*} b 70 | * @return {boolean} 71 | */ 72 | greaterThanOrEqual(a: any, b: any) { 73 | return this.greaterThan(a, b) || this.equal(a, b); 74 | } 75 | 76 | /** 77 | * Invierte el orden de comparación. 78 | */ 79 | reverse() { 80 | const compareOriginal = this.compare; 81 | this.compare = (a: any, b: any) => compareOriginal(b, a); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | 4 | /* Language and Environment */ 5 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 6 | 7 | /* Modules */ 8 | "module": "CommonJS", /* Specify what module code is generated. */ 9 | 10 | /* Interop Constraints */ 11 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 12 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 13 | 14 | /* Type Checking */ 15 | "strict": true, /* Enable all strict type-checking options. */ 16 | "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 17 | "strictFunctionTypes": true, /* Visit https://aka.ms/tsconfig to read more about this file */ /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 18 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 19 | }, 20 | "exclude": [ 21 | "./**/*.test.ts", 22 | ] 23 | } 24 | --------------------------------------------------------------------------------