From c1e3c82b34be448df6574233d901ec62fba5f8c0 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Sun, 22 Dec 2024 21:53:17 -0600 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20Add=20challenge-22=20solution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md | 70 +++++++++++++ .../index.js | 19 ++++ .../index.test.js | 99 +++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 2024/22-genera-combinaciones-de-regalos/README.md create mode 100644 2024/22-genera-combinaciones-de-regalos/index.js create mode 100644 2024/22-genera-combinaciones-de-regalos/index.test.js diff --git a/2024/22-genera-combinaciones-de-regalos/README.md b/2024/22-genera-combinaciones-de-regalos/README.md new file mode 100644 index 0000000..d02c524 --- /dev/null +++ b/2024/22-genera-combinaciones-de-regalos/README.md @@ -0,0 +1,70 @@ +# Reto 22: Genera-combinaciones-de-regalos + +Santa Claus 🎅 está revisando una **lista de juguetes únicos que podría incluir en su bolsa mágica de regalos.** Quiere explorar todas las combinaciones posibles de juguetes. Quiere ver todas las combinaciones que realmente contengan al menos un juguete. + +Tu tarea es escribir una función que, dado un array de juguetes, **devuelva todas las combinaciones posibles.** + +Importante: Debes devolverlo en el orden que aparecen los juguetes y de combinaciones de 1 a n juguetes. + +```js +generateGiftSets(['car', 'doll', 'puzzle']) +// [ +// ['car'], +// ['doll'], +// ['puzzle'], +// ['car', 'doll'], +// ['car', 'puzzle'], +// ['doll', 'puzzle'], +// ['car', 'doll', 'puzzle'] +// ] + +generateGiftSets(['ball']) +// [ +// ['ball'] +// ] + +generateGiftSets(['game', 'pc']) +// [ +// ['game'], +// ['pc'], +// ['game', 'pc'] +// ] +``` + +**Nota: En el array de entrada siempre habrá al menos un juguete y nunca habrá juguetes duplicados.** + +**Consejo**: Hay muchas formas de solucionar este problema, pero el backtracking puede ser una buena opción. 😉 + +## Mi solución explicada + +```js +/* eslint-disable no-inner-declarations */ +function generateGiftSets(gifts) { + const results = []; + function backtracking(start, currentSet) { + if (currentSet.length > 0) { + results.push([...currentSet]); + } + + for (let i = start; i < gifts.length; i++) { + currentSet.push(gifts[i]); + backtracking(i + 1, currentSet); + currentSet.pop(); + } + } + + backtracking(0, []); + + return results.sort((a, b) => a.length - b.length); +} +``` + +Para poder resolver este problema, utilizaremos un enfoque de backtracking. A grandes rasgos, el backtracking es una técnica que consiste en probar todas las posibles combinaciones de una solución, y si en algún momento nos damos cuenta de que no es posible llegar a una solución válida, retrocedemos y probamos otra combinación. + +En este caso, la función `generateGiftSets` recibe un array de juguetes y devuelve todas las combinaciones posibles. Para ello, creamos un array `results` que almacenará todas las combinaciones válidas. + +Dentro de la función `generateGiftSets`, definimos una función interna llamada `backtracking` que se encargará de generar las combinaciones. Esta función recibe dos parámetros: `start` (que indica la posición inicial desde la que se deben considerar los juguetes) y `currentSet` (que es el conjunto actual de juguetes que estamos evaluando). + +En la función `backtracking`, primero verificamos si el conjunto actual `currentSet` tiene al menos un juguete, y si es así, lo agregamos al array `results`. Luego, recorremos los juguetes a partir de la posición `start` y vamos generando las combinaciones de forma recursiva. Para ello, agregamos un juguete al conjunto actual, llamamos a la función `backtracking` con la siguiente posición y el conjunto actual, y luego eliminamos el último juguete agregado para probar con el siguiente. De esta forma, vamos generando todas las combinaciones posibles. + +Finalmente, retornamos el array `results` ordenado por la longitud de cada combinación, de menor a mayor. diff --git a/2024/22-genera-combinaciones-de-regalos/index.js b/2024/22-genera-combinaciones-de-regalos/index.js new file mode 100644 index 0000000..f528b89 --- /dev/null +++ b/2024/22-genera-combinaciones-de-regalos/index.js @@ -0,0 +1,19 @@ +function generateGiftSets(gifts) { + const results = []; + function backtracking(start, currentSet) { + if (currentSet.length > 0) { + results.push([...currentSet]); + } + + for (let i = start; i < gifts.length; i++) { + currentSet.push(gifts[i]); + backtracking(i + 1, currentSet); + currentSet.pop(); + } + } + + backtracking(0, []); + + return results.sort((a, b) => a.length - b.length); +} +module.exports = generateGiftSets; diff --git a/2024/22-genera-combinaciones-de-regalos/index.test.js b/2024/22-genera-combinaciones-de-regalos/index.test.js new file mode 100644 index 0000000..2b1ce26 --- /dev/null +++ b/2024/22-genera-combinaciones-de-regalos/index.test.js @@ -0,0 +1,99 @@ +const generateGiftSets = require('./index'); + +describe('22 => Genera-combinaciones-de-regalos', () => { + const TEST_CASES = [ + { + input: ['car'], + output: [['car']], + }, + { + input: ['car', 'doll', 'puzzle'], + output: [ + ['car'], + ['doll'], + ['puzzle'], + ['car', 'doll'], + ['car', 'puzzle'], + ['doll', 'puzzle'], + ['car', 'doll', 'puzzle'], + ], + }, + { + input: ['car', 'doll'], + output: [['car'], ['doll'], ['car', 'doll']], + }, + { + input: ['apple', 'banana', 'cherry', 'date'], + output: [ + ['apple'], + ['banana'], + ['cherry'], + ['date'], + ['apple', 'banana'], + ['apple', 'cherry'], + ['apple', 'date'], + ['banana', 'cherry'], + ['banana', 'date'], + ['cherry', 'date'], + ['apple', 'banana', 'cherry'], + ['apple', 'banana', 'date'], + ['apple', 'cherry', 'date'], + ['banana', 'cherry', 'date'], + ['apple', 'banana', 'cherry', 'date'], + ], + }, + { + input: ['pen', 'notebook', 'eraser', 'pencil', 'marker'], + output: [ + ['pen'], + ['notebook'], + ['eraser'], + ['pencil'], + ['marker'], + ['pen', 'notebook'], + ['pen', 'eraser'], + ['pen', 'pencil'], + ['pen', 'marker'], + ['notebook', 'eraser'], + ['notebook', 'pencil'], + ['notebook', 'marker'], + ['eraser', 'pencil'], + ['eraser', 'marker'], + ['pencil', 'marker'], + ['pen', 'notebook', 'eraser'], + ['pen', 'notebook', 'pencil'], + ['pen', 'notebook', 'marker'], + ['pen', 'eraser', 'pencil'], + ['pen', 'eraser', 'marker'], + ['pen', 'pencil', 'marker'], + ['notebook', 'eraser', 'pencil'], + ['notebook', 'eraser', 'marker'], + ['notebook', 'pencil', 'marker'], + ['eraser', 'pencil', 'marker'], + ['pen', 'notebook', 'eraser', 'pencil'], + ['pen', 'notebook', 'eraser', 'marker'], + ['pen', 'notebook', 'pencil', 'marker'], + ['pen', 'eraser', 'pencil', 'marker'], + ['notebook', 'eraser', 'pencil', 'marker'], + ['pen', 'notebook', 'eraser', 'pencil', 'marker'], + ], + }, + { + input: [], + output: [], + }, + ]; + + it('should return array type', () => { + const result = generateGiftSets(['car']); + expect(Array.isArray(result)).toBe(true); + }); + + it.each(TEST_CASES)( + 'should return an array with $output.length elements', + ({ input, output }) => { + const result = generateGiftSets(input); + expect(result).toHaveLength(output.length); + }, + ); +}); From 5de2eae33703931a31b3b11db245f7a7f883d337 Mon Sep 17 00:00:00 2001 From: Marco Cruz Date: Sun, 22 Dec 2024 21:56:12 -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 | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f16d422..0f92d4c 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ npm run test 'year'/'challenge'/index.test.js | 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) | ⭐⭐⭐⭐⭐ | | 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) | ⭐⭐⭐⭐⭐ | Difficulties legend: 🟢 Easy 🟡 Medium 🔴 Hard