From 2784b927a85be74e77b1a739dbddba0c7deb3e94 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Sat, 21 Dec 2024 17:39:14 -0600 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20Add=20challenge-20=20solution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 251 ++++++++++++++++++ .../index.js | 19 ++ .../index.test.js | 109 ++++++++ 3 files changed, 379 insertions(+) create mode 100644 2024/20-encuentra-los-regalos-faltantes-y-duplicados/README.md create mode 100644 2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.js create mode 100644 2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.test.js diff --git a/2024/20-encuentra-los-regalos-faltantes-y-duplicados/README.md b/2024/20-encuentra-los-regalos-faltantes-y-duplicados/README.md new file mode 100644 index 0000000..39757f2 --- /dev/null +++ b/2024/20-encuentra-los-regalos-faltantes-y-duplicados/README.md @@ -0,0 +1,251 @@ +# Reto 20: Encuentra-los-regalos-faltantes-y-duplicados + +**Santa Claus** 🎅 está revisando la lista de regalos que debe entregar esta Navidad. Sin embargo, **algunos regalos faltan, otros están duplicados, y algunos tienen cantidades incorrectas.** Necesita tu ayuda para resolver el problema. + +Recibirás dos arrays: + +- `received`: Lista con los regalos que Santa tiene actualmente. +- `expected`: Lista con los regalos que Santa debería tener. + +Tu tarea es escribir una función que, dado received y expected, devuelva un objeto con dos propiedades: + +- `missing`: Un objeto donde las claves son los nombres de los regalos faltantes y los valores son las cantidades que faltan. +- `extra`: Un objeto donde las claves son los nombres de los regalos extra o duplicados y los valores son las cantidades que sobran. + +Ten en cuenta que: + +- Los regalos pueden repetirse en ambas listas. +- Las listas de regalos están desordenadas. +- Si no hay regalos que falten o sobren, las propiedades correspondientes (`missing o extra`) deben ser objetos vacíos. + +```js +fixGiftList(['puzzle', 'car', 'doll', 'car'], ['car', 'puzzle', 'doll', 'ball']) +// Devuelve: +// { +// missing: { ball: 1 }, +// extra: { car: 1 } +// } + +fixGiftList( + ['book', 'train', 'kite', 'train'], + ['train', 'book', 'kite', 'ball', 'kite'] +) +// Devuelve: +// { +// missing: { ball: 1, kite: 1 }, +// extra: { train: 1 } +// } + +fixGiftList( + ['bear', 'bear', 'car'], + ['bear', 'car', 'puzzle', 'bear', 'car', 'car'] +) +// Devuelve: +// { +// missing: { puzzle: 1, car: 2 }, +// extra: {} +// } + +fixGiftList(['bear', 'bear', 'car'], ['car', 'bear', 'bear']) +// Devuelve: +// { +// missing: {}, +// extra: {} +// } +``` + +## Mi solución explicada + +```js +function fixGiftList(received, expected) { + const counts = {}; + + for (const gift of received) counts[gift] = ~~counts[gift] + 1; + for (const gift of expected) counts[gift] = ~~counts[gift] - 1; + + const missing = {}; + const extra = {}; + for (const [gift, count] of Object.entries(counts)) { + if (count > 0) extra[gift] = count; + else if (count < 0) missing[gift] = -count; + } + + return { missing, extra }; +} + +module.exports = fixGiftList; +``` + +Para resolver este reto, hay que tener en cuenta que necesitamos comparar dos listas de regalos: `received` y `expected`. Para ello, vamos a recorrer ambas listas y vamos a ir contando cuántas veces aparece cada regalo en cada una de ellas. + +Para llevar la cuenta de los regalos, vamos a utilizar un objeto llamado `counts`. Este objeto va a tener como claves los nombres de los regalos y como valores la cantidad de veces que aparece cada regalo en la lista. + +Como no sabemos si un regalo se repite en ambas listas, vamos a recorrer la lista `received` y vamos a incrementar en 1 la cantidad de veces que aparece cada regalo en el objeto `counts`. Luego, vamos a recorrer la lista `expected` y vamos a decrementar en 1 la cantidad de veces que aparece cada regalo en el objeto `counts`. De esta forma, si un regalo aparece en ambas listas, la cantidad de veces que aparece en el objeto `counts` será 0. Si un regalo aparece más veces en `received` que en `expected`, la cantidad será positiva. Si un regalo aparece más veces en `expected` que en `received`, la cantidad será negativa. Si un regalo no aparece en ninguna de las listas, la cantidad será 0. + +Una vez que tenemos el objeto `counts` con la cantidad de veces que aparece cada regalo en ambas listas, vamos a recorrer este objeto y vamos a crear dos objetos: `missing` y `extra`. En el objeto `missing` vamos a guardar los regalos que faltan y en el objeto `extra` vamos a guardar los regalos que sobran. Para ello, vamos a recorrer el objeto `counts` y vamos a verificar si la cantidad de veces que aparece un regalo es mayor que 0. Si es así, significa que ese regalo sobra y lo agregamos al objeto `extra`. Si la cantidad es menor que 0, significa que ese regalo falta y lo agregamos al objeto `missing`. + +Finalmente, devolvemos un objeto con las propiedades `missing` y `extra`, que contienen los regalos que faltan y sobran, respectivamente. + +**Veamos con un ejemplo cómo funciona el código:** + +Supongamos que recibimos las listas `received` y `expected` siguientes: + +```js +const received = ['car', 'puzzle', 'car']; +const expected = ['puzzle', 'car', 'doll']; +``` + +Utilizaremos un ciclo `for...of` para recorrer la lista `received` y vamos a incrementar en 1 la cantidad de veces que aparece cada regalo en el objeto `counts`. + +Recorremos la lista `received` y como esta lista tiene 3 elementos, el ciclo se ejecutará 3 veces. En la primera iteración, el regalo es `'car'`. Como el objeto `counts` está vacío, la cantidad de veces que aparece el regalo `'car'` es `undefined`. Al utilizar el operador `~~` para convertir el valor a un número entero, obtenemos `0`. Luego, incrementamos en 1 la cantidad de veces que aparece el regalo `'car'` en el objeto `counts`. Ahora, el objeto `counts` es `{ car: 1 }`. + +```js +// counts[gift] = ~~counts[gift] + 1; +// counts['car'] = ~~counts['car'] + 1; +// counts['car'] = ~~undefined + 1; +// counts['car'] = 0 + 1; +counts['car'] = 1; + +const counts = { car: 1 }; +``` + +En la segunda iteración tenemos el regalo `'puzzle'`. Al igual que en la iteración anterior, la cantidad de veces que aparece el regalo `'puzzle'` es `undefined`. Al convertir este valor a un número entero, obtenemos `0`. Luego, incrementamos en 1 la cantidad de veces que aparece el regalo `'puzzle'` en el objeto `counts`. Ahora, el objeto `counts` es `{ car: 1, puzzle: 1 }`. + +```js +// counts[gift] = ~~counts[gift] + 1; +// counts['puzzle'] = ~~counts['puzzle'] + 1; +// counts['puzzle'] = ~~undefined + 1; +// counts['puzzle'] = 0 + 1; +counts['puzzle'] = 1; + +const counts = { car: 1, puzzle: 1 }; +``` + +En la tercera y última iteración, el regalo es `'car'`. La cantidad de veces que aparece el regalo `'car'` en el objeto `counts` es `1`. Al incrementar en 1 esta cantidad, obtenemos `2`. Ahora, el objeto `counts` es `{ car: 2, puzzle: 1 }`. + +```js +// counts[gift] = ~~counts[gift] + 1; +// counts['car'] = ~~counts['car'] + 1; +// counts['car'] = ~~1 + 1; +// counts['car'] = 1 + 1; +counts['car'] = 2; + +const counts = { car: 2, puzzle: 1 }; +``` + +Luego, recorremos la lista `expected` y vamos a decrementar en 1 la cantidad de veces que aparece cada regalo en el objeto `counts`. + +Recorremos la lista `expected` y como esta lista tiene 3 elementos, el ciclo se ejecutará 3 veces. En la primera iteración, el regalo es `'puzzle'`. La cantidad de veces que aparece el regalo `'puzzle'` en el objeto `counts` es `1`. Al decrementar en 1 esta cantidad, obtenemos `0`. Ahora, el objeto `counts` es `{ car: 2, puzzle: 0 }`. + +```js +// counts[gift] = ~~counts[gift] - 1; +// counts['puzzle'] = ~~counts['puzzle'] - 1; +// counts['puzzle'] = ~~1 - 1; +// counts['puzzle'] = 1 - 1; +counts['puzzle'] = 0; + +const counts = { car: 2, puzzle: 0 }; +``` + +En la segunda iteración tenemos el regalo `'car'`. La cantidad de veces que aparece el regalo `'car'` en el objeto `counts` es `2`. Al decrementar en 1 esta cantidad, obtenemos `1`. Ahora, el objeto `counts` es `{ car: 1, puzzle: 0 }`. + +```js +// counts[gift] = ~~counts[gift] - 1; +// counts['car'] = ~~counts['car'] - 1; +// counts['car'] = ~~2 - 1; +// counts['car'] = 2 - 1; +counts['car'] = 1; + +const counts = { car: 1, puzzle: 0 }; +``` + +En la tercera y última iteración, el regalo es `'doll'`. La cantidad de veces que aparece el regalo `'doll'` en el objeto `counts` es `undefined`. Al convertir este valor a un número entero, obtenemos `0`. Al decrementar en 1 esta cantidad, obtenemos `-1`. Ahora, el objeto `counts` es `{ car: 1, puzzle: 0, doll: -1 }`. + +```js +// counts[gift] = ~~counts[gift] - 1; +// counts['doll'] = ~~counts['doll'] - 1; +// counts['doll'] = ~~undefined - 1; +// counts['doll'] = 0 - 1; +counts['doll'] = -1; + +const counts = { car: 1, puzzle: 0, doll: -1 }; +``` + +Una vez que tenemos el objeto `counts` con la cantidad de veces que aparece cada regalo en ambas listas, vamos a recorrer este objeto y vamos a crear dos objetos: `missing` y `extra`. + +Nuevamente, utilizaremos un ciclo `for...of` para recorrer el objeto `counts`. Aquí utilizaremos el método `Object.entries()` para obtener un array con las claves y valores del objeto `counts`. Luego, recorreremos este array con un ciclo `for...of` y vamos a verificar si la cantidad de veces que aparece un regalo es mayor que 0. Si es así, significa que ese regalo sobra y lo agregamos al objeto `extra`. Si la cantidad es menor que 0, significa que ese regalo falta y lo agregamos al objeto `missing`. + +Entonces para el objeto `counts` que tenemos, el array que obtenemos con `Object.entries(counts)` es el siguiente: + +```js +const entries = [ + ['car', 1], + ['puzzle', 0], + ['doll', -1] +]; +``` + +En la primera iteración, la clave es `'car'` y el valor es `1`. Como el valor es mayor que 0, agregamos el regalo `'car'` al objeto `extra` con la cantidad `1`. + +```js +gift = 'car'; +count = 1; + +// if (count > 0) extra[gift] = count; +// if (1 > 0) extra['car'] = 1; +// if (true) extra['car'] = 1; +extra['car'] = 1; + +const extra = { car: 1 }; +const missing = {}; +``` + +En la segunda iteración, la clave es `'puzzle'` y el valor es `0`. Como el valor es igual a 0, no hacemos nada. + +```js +gift = 'puzzle'; +count = 0; + +// if (count > 0) extra[gift] = count; +// if (0 > 0) extra['puzzle'] = 0; +// if (false) extra['puzzle'] = 0; (no se ejecuta) + +// else if (count < 0) missing[gift] = -count; +// else if (0 < 0) missing['puzzle'] = 0; +// else if (false) missing['puzzle'] = 0; (no se ejecuta) + +const extra = { car: 1 }; +const missing = {}; +``` + +En la tercera y última iteración, la clave es `'doll'` y el valor es `-1`. Como el valor es menor que 0, agregamos el regalo `'doll'` al objeto `missing` con la cantidad `1`. + +```js +gift = 'doll'; +count = -1; + +// if (count > 0) extra[gift] = count; +// if (-1 > 0) extra['doll'] = -1; +// if (false) extra['doll'] = -1; (no se ejecuta) + +// else if (count < 0) missing[gift] = -count; +// else if (-1 < 0) missing['doll'] = -(-1); +// else if (true) missing['doll'] = 1; +missing['doll'] = 1; + +const extra = { car: 1 }; +const missing = { doll: 1 }; +``` + +Finalmente, devolvemos un objeto con las propiedades `missing` y `extra`, que contienen los regalos que faltan y sobran, respectivamente. + +```js +{ + missing: { doll: 1 }, + extra: { car: 1 } +} +``` + +En este caso, el regalo `'doll'` falta y el regalo `'car'` sobra. + +Y con esto hemos terminado de resolver el reto. 🎉 diff --git a/2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.js b/2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.js new file mode 100644 index 0000000..4f1a07e --- /dev/null +++ b/2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.js @@ -0,0 +1,19 @@ +/* eslint-disable no-bitwise */ +/* eslint-disable no-restricted-syntax */ +function fixGiftList(received, expected) { + const counts = {}; + + for (const gift of received) counts[gift] = ~~counts[gift] + 1; + for (const gift of expected) counts[gift] = ~~counts[gift] - 1; + + const missing = {}; + const extra = {}; + for (const [gift, count] of Object.entries(counts)) { + if (count > 0) extra[gift] = count; + else if (count < 0) missing[gift] = -count; + } + + return { missing, extra }; +} + +module.exports = fixGiftList; diff --git a/2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.test.js b/2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.test.js new file mode 100644 index 0000000..b4e5555 --- /dev/null +++ b/2024/20-encuentra-los-regalos-faltantes-y-duplicados/index.test.js @@ -0,0 +1,109 @@ +const fixGiftList = require('./index'); + +describe('20 => Encuentra-los-regalos-faltantes-y-duplicados', () => { + const TEST_CASES = [ + { + input: [ + ['puzzle', 'car'], + ['puzzle', 'car', 'ball'], + ], + output: { + missing: { + ball: 1, + }, + extra: {}, + }, + }, + { + input: [ + ['car', 'puzzle', 'car'], + ['puzzle', 'car', 'doll'], + ], + output: { + missing: { + doll: 1, + }, + extra: { + car: 1, + }, + }, + }, + { + input: [ + ['train', 'book', 'kite'], + ['train', 'kite', 'book', 'kite'], + ], + output: { + missing: { + kite: 1, + }, + extra: {}, + }, + }, + { + input: [ + ['bear', 'car'], + ['bear', 'car', 'car'], + ], + output: { + missing: { + car: 1, + }, + extra: {}, + }, + }, + { + input: [[], ['bear', 'car', 'car']], + output: { + missing: { + bear: 1, + car: 2, + }, + extra: {}, + }, + }, + { + input: [ + ['puzzle', 'puzzle', 'car'], + ['puzzle', 'car'], + ], + output: { + missing: {}, + extra: { + puzzle: 1, + }, + }, + }, + { + input: [['car'], ['car', 'puzzle', 'ball']], + output: { + missing: { + puzzle: 1, + ball: 1, + }, + extra: {}, + }, + }, + { + input: [ + ['bear', 'bear', 'car'], + ['bear', 'bear', 'car'], + ], + output: { + missing: {}, + extra: {}, + }, + }, + ]; + + it('should return an object', () => { + const testCase = TEST_CASES[0]; + const received = fixGiftList(...testCase.input); + expect(received).toEqual(expect.any(Object)); + }); + + it.each(TEST_CASES)('should return the correct object', (testCase) => { + const received = fixGiftList(...testCase.input); + expect(received).toEqual(testCase.output); + }); +}); From 995f5470e3905f9fe5c389b21246b3c6df52ea59 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Sat, 21 Dec 2024 17:39:47 -0600 Subject: [PATCH 2/2] =?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 | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 46c7b86..b01bcc5 100644 --- a/README.md +++ b/README.md @@ -57,25 +57,26 @@ npm run test 'year'/'challenge'/index.test.js
Show / Hide -| # | Challenge | Difficulty | My Solution | My Explanation | My Score | -| :-: | ------------------------------------------------------------------------------------------- | :--------: | :-----------------------------------------------------------: |:------------------------------------------------------------------------------: | :----------- | -| 01 | [🎁 ¡Primer regalo repetido!](https://adventjs.dev/es/challenges/2024/1) | 🟢 | [here](./2024/01-primer-regalo-repetido/index.js) | [here](./2024/01-primer-regalo-repetido/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 02 | [🖼️ Enmarcando nombres](https://adventjs.dev/es/challenges/2024/2) | 🟢 | [here](./2024/02-enmarcando-nombres/index.js) | [here](./2024/02-enmarcando-nombres/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 03 | [🏗️ Organizando el inventario](https://adventjs.dev/es/challenges/2024/3) | 🟢 | [here](./2024/03-organizando-el-inventario/index.js) | [here](./2024/03-organizando-el-inventario/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 04 | [🎄 Decorando el árbol de Navidad](https://adventjs.dev/es/challenges/2024/4) | 🟡 | [here](./2024/04-decorando-el-arbol-de-navidad/index.js) | [here](./2024/04-decorando-el-arbol-de-navidad/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 05 | [👢 Emparejando botas](https://adventjs.dev/es/challenges/2024/5) | 🟢 | [here](./2024/05-emparejando-botas/index.js) | [here](./2024/05-emparejando-botas/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 06 | [🎁 ¿Regalo dentro de la caja?](https://adventjs.dev/es/challenges/2024/6) | 🟡 | [here](./2024/06-regalo-dentro-de-la-caja/index.js) | [here](./2024/06-regalo-dentro-de-la-caja/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 07 | [🎅🏼 El ataque del Grinch](https://adventjs.dev/es/challenges/2024/7) | 🟡 | [here](./2024/07-el-ataque-del-grinch/index.js) | [here](./2024/07-el-ataque-del-grinch/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 08 | [🦌 La carrera de renos](https://adventjs.dev/es/challenges/2024/8) | 🟢 | [here](./2024/08-la-carrera-de-renos/index.js) | [here](./2024/08-la-carrera-de-renos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 09 | [🚂 El tren mágico](https://adventjs.dev/es/challenges/2024/9) | 🟡 | [here](./2024/09-el-tren-magico/index.js) | [here](./2024/09-el-tren-magico/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 10 | [🧑‍💻 El ensamblador élfico](https://adventjs.dev/es/challenges/2024/10) | 🟡 | [here](./2024/10-el-ensamblador-elfico/index.js) | [here](./2024/10-el-ensamblador-elfico/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 11 | [📂 Nombres de archivos codificados](https://adventjs.dev/es/challenges/2024/11) | 🟢 | [here](./2024/11-nombres-de-archivos-codificados/index.js) | [here](./2024/11-nombres-de-archivos-codificados/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 12 | [🎄 ¿Cuánto cuesta el árbol?](https://adventjs.dev/es/challenges/2024/12) | 🟢 | [here](./2024/12-cuanto-cuesta-el-arbol/index.js) | [here](./2024/12-cuanto-cuesta-el-arbol/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 13 | [🤖 ¿El robot está de vuelta?](https://adventjs.dev/es/challenges/2024/13) | 🔴 | [here](./2024/13-el-robot-esta-de-vuelta/index.js) | [here](./2024/13-el-robot-esta-de-vuelta/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 14 | [🦌 Acomodando los renos](https://adventjs.dev/es/challenges/2024/14) | 🟢 | [here](./2024/14-acomodando-los-renos/index.js) | [here](./2024/14-acomodando-los-renos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 15 | [✏️ Dibujando tablas](https://adventjs.dev/es/challenges/2024/15) | 🟢 | [here](./2024/15-dibujando-tablas/index.js) | [here](./2024/15-dibujando-tablas/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 16 | [❄️ Limpiando la nieve del camino](https://adventjs.dev/es/challenges/2024/16) | 🟢 | [here](./2024/16-limpiando-la-nieve-del-camino/index.js) | [here](./2024/16-limpiando-la-nieve-del-camino/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | -| 17 | [💣 Busca las bombas del Grinch](https://adventjs.dev/es/challenges/2024/17) | 🟡 | [here](./2024/17-busca-las-bombas-del-grinch/index.js) | [here](./2024/17-busca-las-bombas-del-grinch/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| # | Challenge | Difficulty | My Solution | My Explanation | My Score | +| :-: | ------------------------------------------------------------------------------------------- | :--------: | :------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------:| :----------- | +| 01 | [🎁 ¡Primer regalo repetido!](https://adventjs.dev/es/challenges/2024/1) | 🟢 | [here](./2024/01-primer-regalo-repetido/index.js) | [here](./2024/01-primer-regalo-repetido/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 02 | [🖼️ Enmarcando nombres](https://adventjs.dev/es/challenges/2024/2) | 🟢 | [here](./2024/02-enmarcando-nombres/index.js) | [here](./2024/02-enmarcando-nombres/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 03 | [🏗️ Organizando el inventario](https://adventjs.dev/es/challenges/2024/3) | 🟢 | [here](./2024/03-organizando-el-inventario/index.js) | [here](./2024/03-organizando-el-inventario/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 04 | [🎄 Decorando el árbol de Navidad](https://adventjs.dev/es/challenges/2024/4) | 🟡 | [here](./2024/04-decorando-el-arbol-de-navidad/index.js) | [here](./2024/04-decorando-el-arbol-de-navidad/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 05 | [👢 Emparejando botas](https://adventjs.dev/es/challenges/2024/5) | 🟢 | [here](./2024/05-emparejando-botas/index.js) | [here](./2024/05-emparejando-botas/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 06 | [🎁 ¿Regalo dentro de la caja?](https://adventjs.dev/es/challenges/2024/6) | 🟡 | [here](./2024/06-regalo-dentro-de-la-caja/index.js) | [here](./2024/06-regalo-dentro-de-la-caja/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 07 | [🎅🏼 El ataque del Grinch](https://adventjs.dev/es/challenges/2024/7) | 🟡 | [here](./2024/07-el-ataque-del-grinch/index.js) | [here](./2024/07-el-ataque-del-grinch/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 08 | [🦌 La carrera de renos](https://adventjs.dev/es/challenges/2024/8) | 🟢 | [here](./2024/08-la-carrera-de-renos/index.js) | [here](./2024/08-la-carrera-de-renos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 09 | [🚂 El tren mágico](https://adventjs.dev/es/challenges/2024/9) | 🟡 | [here](./2024/09-el-tren-magico/index.js) | [here](./2024/09-el-tren-magico/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 10 | [🧑‍💻 El ensamblador élfico](https://adventjs.dev/es/challenges/2024/10) | 🟡 | [here](./2024/10-el-ensamblador-elfico/index.js) | [here](./2024/10-el-ensamblador-elfico/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 11 | [📂 Nombres de archivos codificados](https://adventjs.dev/es/challenges/2024/11) | 🟢 | [here](./2024/11-nombres-de-archivos-codificados/index.js) | [here](./2024/11-nombres-de-archivos-codificados/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 12 | [🎄 ¿Cuánto cuesta el árbol?](https://adventjs.dev/es/challenges/2024/12) | 🟢 | [here](./2024/12-cuanto-cuesta-el-arbol/index.js) | [here](./2024/12-cuanto-cuesta-el-arbol/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 13 | [🤖 ¿El robot está de vuelta?](https://adventjs.dev/es/challenges/2024/13) | 🔴 | [here](./2024/13-el-robot-esta-de-vuelta/index.js) | [here](./2024/13-el-robot-esta-de-vuelta/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 14 | [🦌 Acomodando los renos](https://adventjs.dev/es/challenges/2024/14) | 🟢 | [here](./2024/14-acomodando-los-renos/index.js) | [here](./2024/14-acomodando-los-renos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 15 | [✏️ Dibujando tablas](https://adventjs.dev/es/challenges/2024/15) | 🟢 | [here](./2024/15-dibujando-tablas/index.js) | [here](./2024/15-dibujando-tablas/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 16 | [❄️ Limpiando la nieve del camino](https://adventjs.dev/es/challenges/2024/16) | 🟢 | [here](./2024/16-limpiando-la-nieve-del-camino/index.js) | [here](./2024/16-limpiando-la-nieve-del-camino/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 17 | [💣 Busca las bombas del Grinch](https://adventjs.dev/es/challenges/2024/17) | 🟡 | [here](./2024/17-busca-las-bombas-del-grinch/index.js) | [here](./2024/17-busca-las-bombas-del-grinch/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ | +| 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) | ⭐⭐⭐⭐⭐ | Difficulties legend: 🟢 Easy 🟡 Medium 🔴 Hard