From 4dbaa1b51118196544e63146cb3504756381f8d3 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Mon, 23 Dec 2024 12:50:52 -0600 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=A8=20Add=20challenge-23=20solution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 105 ++++++++++++++++++ .../index.js | 11 ++ .../index.test.js | 39 +++++++ 3 files changed, 155 insertions(+) create mode 100644 2024/23-encuentra-los-numeros-perdidos/README.md create mode 100644 2024/23-encuentra-los-numeros-perdidos/index.js create mode 100644 2024/23-encuentra-los-numeros-perdidos/index.test.js diff --git a/2024/23-encuentra-los-numeros-perdidos/README.md b/2024/23-encuentra-los-numeros-perdidos/README.md new file mode 100644 index 0000000..ea62639 --- /dev/null +++ b/2024/23-encuentra-los-numeros-perdidos/README.md @@ -0,0 +1,105 @@ +# Reto 23: Encuentra-los-numeros-perdidos + +Los elfos están trabajando en un sistema para verificar las listas de regalos de los niños 👧👦. Sin embargo, ¡algunas listas están incompletas y **faltan números**! + +Tu tarea es escribir **una función que, dado un array de números, encuentre todos los números que faltan entre 1 y n** (donde n es el tamaño del array o el número más alto del array). + +Eso sí, ten en cuenta que: + +- Los números pueden aparecer más de una vez y otros pueden faltar +- El array siempre contiene números enteros positivos +- Siempre se empieza a contar desde el 1 + +```js +findMissingNumbers([1, 2, 4, 6]) +// [3, 5] + +findMissingNumbers([4, 8, 7, 2]) +// [1, 3, 5, 6] + +findMissingNumbers([3, 2, 1, 1]) +// [] + +findDisappearedNumbers([5, 5, 5, 3, 3, 2, 1]) +// [4] +``` + +## Mi solución explicada + +```js +function findMissingNumbers(nums) { + const maxNumber = Math.max(...nums); + const fullSetOfNumbers = new Set( + Array.from({ length: maxNumber }, (_, index) => index + 1), + ); + const uniqueNumbers = new Set(nums); + const missingNumbers = fullSetOfNumbers.difference(uniqueNumbers); + return [...missingNumbers]; +} +``` + +Para resolver este reto, utilice diferencia de conjuntos. Esto consiste en crear un conjunto con todos los números del 1 al número más alto del array, luego crear un conjunto con los números únicos del array y finalmente obtener la diferencia entre ambos conjuntos. + +Para esto utilice el método `Math.max` para obtener el número más alto del array, luego cree un conjunto con todos los números del 1 al número más alto del array utilizando `Array.from` y `Set`. Después cree un conjunto con los números únicos del array utilizando `Set`. Finalmente obtuve la diferencia entre ambos conjuntos y devolví un array con los números faltantes. + +**Veamos un ejemplo**: + +Supongamos que tenemos el siguiente array: + +```js +const nums = [1, 2, 4, 6]; +``` + +Primero obtenemos el número más alto del array, en este caso es el número 6: + +```js +const maxNumber = Math.max(...nums); +// const maxNumber = Math.max(...[1, 2, 4, 6]); +// const maxNumber = Math.max(1, 2, 4, 6); +const maxNumber = 6; +``` + +Luego creamos un conjunto con todos los números del 1 al número más alto del array, para este caso utilizamos `Array.from` y `Set`, donde `Array.from` crea un array con los números del 1 al 6 y `Set` convierte ese array en un conjunto: + +```js +const fullSetOfNumbers = new Set( + Array.from({ length: maxNumber }, (_, index) => index + 1), +); + +// Array.from({ length: 6 }, (_, index) => index + 1); +// Array.from([undefined, undefined, undefined, undefined, undefined, undefined], (_, index) => index + 1); +// [1, 2, 3, 4, 5, 6] + +// new Set([1, 2, 3, 4, 5, 6]); + +const fullSetOfNumbers = new Set([1, 2, 3, 4, 5, 6]); +``` + +Después creamos un conjunto con los números únicos del array, para este caso utilizamos `Set`: + +```js +const uniqueNumbers = new Set(nums); +// const uniqueNumbers = new Set([1, 2, 4, 6]); +const uniqueNumbers = new Set([1, 2, 4, 6]); +``` + +Finalmente obtenemos la diferencia entre ambos conjuntos, para esto utilizamos el método `difference` que creamos previamente: + +```js +const missingNumbers = fullSetOfNumbers.difference(uniqueNumbers); +// const missingNumbers = [1, 2, 3, 4, 5, 6].difference([1, 2, 4, 6]); +// const missingNumbers = [3, 5]; +const missingNumbers = [3, 5]; +``` + +`difference` lo que hace es obtener la diferencia entre ambos conjuntos, es decir, los números que están en el primer conjunto pero no en el segundo. Por ejemplo: la diferencia de elementos que esta en `fullSetOfNumbers` pero no en `uniqueNumbers`, es decir, si `fullSetOfNumbers` es `[1, 2, 3, 4, 5, 6]` y `uniqueNumbers` es `[1, 2, 4, 6]`, entonces la diferencia es `[3, 5]`, que son los números faltantes. + +Y devolvemos un array con los números faltantes: + +```js +return [...missingNumbers]; +// return [3, 5]; +return [3, 5]; +``` + +Así es como resolví este reto utilizando diferencia de conjuntos 🎉 diff --git a/2024/23-encuentra-los-numeros-perdidos/index.js b/2024/23-encuentra-los-numeros-perdidos/index.js new file mode 100644 index 0000000..36276ee --- /dev/null +++ b/2024/23-encuentra-los-numeros-perdidos/index.js @@ -0,0 +1,11 @@ +function findMissingNumbers(nums) { + const maxNumber = Math.max(...nums); + const fullSetOfNumbers = new Set( + Array.from({ length: maxNumber }, (_, index) => index + 1), + ); + const uniqueNumbers = new Set(nums); + const missingNumbers = fullSetOfNumbers.difference(uniqueNumbers); + return [...missingNumbers]; +} + +module.exports = findMissingNumbers; diff --git a/2024/23-encuentra-los-numeros-perdidos/index.test.js b/2024/23-encuentra-los-numeros-perdidos/index.test.js new file mode 100644 index 0000000..cb75a6b --- /dev/null +++ b/2024/23-encuentra-los-numeros-perdidos/index.test.js @@ -0,0 +1,39 @@ +const findMissingNumbers = require('./index'); + +describe('23 => Encuentra-los-numeros-perdidos', () => { + const TEST_CASES = [ + { + input: [1, 2, 4, 6], + output: [3, 5], + }, + { + input: [4, 8, 7, 2], + output: [1, 3, 5, 6], + }, + { + input: [3, 2, 1, 1], + output: [], + }, + { + input: [5, 5, 5, 3, 3, 2, 1], + output: [4], + }, + { + input: [1, 2, 3, 4, 5], + output: [], + }, + ]; + + it('should return an array', () => { + const result = findMissingNumbers([1, 2, 4, 6]); + expect(Array.isArray(result)).toBe(true); + }); + + it.each(TEST_CASES)( + 'should return the missing numbers', + ({ input, output }) => { + const result = findMissingNumbers(input); + expect(result).toEqual(output); + }, + ); +}); From 0ab4a997926de8e043de89713bc0a0bda81b3aea Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Mon, 23 Dec 2024 12:52:37 -0600 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9D=20Update=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fba5093..f53c0f4 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ npm run test 'year'/'challenge'/index.test.js | 20 | [🎁 Encuentra los regalos faltantes y duplicados](https://adventjs.dev/es/challenges/2024/20) | 🟢 | [here](./2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.js) | [here](./2024/20-encuentra-los-regalos-faltantes-y-duplicados/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | | 21 | [🎄 Calcula la altura del árbol de Navidad](https://adventjs.dev/es/challenges/2024/21) | 🟢 | [here](./2024/21-calcula-la-altura-del-arbol-de-navidad/index.js) | [here](./2024/21-calcula-la-altura-del-arbol-de-navidad/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | | 22 | [🎁 Genera combinaciones de regalos](https://adventjs.dev/es/challenges/2024/22) | 🟡 | [here](./2024/22-genera-combinaciones-de-regalos/index.js) | [here](./2024/22-genera-combinaciones-de-regalos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 23 | [🔢 Encuentra los números perdidos](https://adventjs.dev/es/challenges/2024/23) | 🟢 | [here](./2024/23-encuentra-los-numeros-perdidos/index.js) | [here](./2024/23-encuentra-los-numeros-perdidos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | Difficulties legend: 🟢 Easy 🟡 Medium 🔴 Hard From 3221eb9cbdcc95c7f91fb4a70fd99763eda369f8 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Mon, 23 Dec 2024 13:05:16 -0600 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9C=A8=20Add=20Set.prototype.difference?= =?UTF-8?q?=20method=20for=20compatibility=20with=20older=20Node.js=20vers?= =?UTF-8?q?ions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2024/23-encuentra-los-numeros-perdidos/index.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/2024/23-encuentra-los-numeros-perdidos/index.js b/2024/23-encuentra-los-numeros-perdidos/index.js index 36276ee..f752fb3 100644 --- a/2024/23-encuentra-los-numeros-perdidos/index.js +++ b/2024/23-encuentra-los-numeros-perdidos/index.js @@ -1,3 +1,13 @@ +/* eslint-disable func-names */ +/* eslint-disable no-extend-native */ +Set.prototype.difference = function (set) { + return new Set([...this].filter((x) => !set.has(x))); +}; + +// La función de set.difference() esta disponible desde la version 22 de nodejs +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/difference#browser_compatibility +// Para poder utilizarla en versiones anteriores de nodejs, se debe de agregar la función al prototipo de Set + function findMissingNumbers(nums) { const maxNumber = Math.max(...nums); const fullSetOfNumbers = new Set( From 920dc595f89221eacd70f439a5ad4668041b3272 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Mon, 23 Dec 2024 13:09:40 -0600 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=A8=20Add=20challenge-23=20solution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2024/23-encuentra-los-numeros-perdidos/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/2024/23-encuentra-los-numeros-perdidos/README.md b/2024/23-encuentra-los-numeros-perdidos/README.md index ea62639..5ab32a4 100644 --- a/2024/23-encuentra-los-numeros-perdidos/README.md +++ b/2024/23-encuentra-los-numeros-perdidos/README.md @@ -26,6 +26,14 @@ findDisappearedNumbers([5, 5, 5, 3, 3, 2, 1]) ## Mi solución explicada +**NOTA** Para correr este código necesitas la versión 22 o superior de Node.js. En caso contrario, puedes crear una función `difference` que haga lo mismo que `Set.prototype.difference`. + +```js +Set.prototype.difference = function (set) { + return new Set([...this].filter((x) => !set.has(x))); +}; +``` + ```js function findMissingNumbers(nums) { const maxNumber = Math.max(...nums);