Skip to content

Commit b2a1217

Browse files
authored
Merge pull request #38 from marcode24/2024-22
✨ Add challenge-22 solution
2 parents f962cc0 + 5de2eae commit b2a1217

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Reto 22: Genera-combinaciones-de-regalos
2+
3+
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.
4+
5+
Tu tarea es escribir una función que, dado un array de juguetes, **devuelva todas las combinaciones posibles.**
6+
7+
Importante: Debes devolverlo en el orden que aparecen los juguetes y de combinaciones de 1 a n juguetes.
8+
9+
```js
10+
generateGiftSets(['car', 'doll', 'puzzle'])
11+
// [
12+
// ['car'],
13+
// ['doll'],
14+
// ['puzzle'],
15+
// ['car', 'doll'],
16+
// ['car', 'puzzle'],
17+
// ['doll', 'puzzle'],
18+
// ['car', 'doll', 'puzzle']
19+
// ]
20+
21+
generateGiftSets(['ball'])
22+
// [
23+
// ['ball']
24+
// ]
25+
26+
generateGiftSets(['game', 'pc'])
27+
// [
28+
// ['game'],
29+
// ['pc'],
30+
// ['game', 'pc']
31+
// ]
32+
```
33+
34+
**Nota: En el array de entrada siempre habrá al menos un juguete y nunca habrá juguetes duplicados.**
35+
36+
**Consejo**: Hay muchas formas de solucionar este problema, pero el backtracking puede ser una buena opción. 😉
37+
38+
## Mi solución explicada
39+
40+
```js
41+
/* eslint-disable no-inner-declarations */
42+
function generateGiftSets(gifts) {
43+
const results = [];
44+
function backtracking(start, currentSet) {
45+
if (currentSet.length > 0) {
46+
results.push([...currentSet]);
47+
}
48+
49+
for (let i = start; i < gifts.length; i++) {
50+
currentSet.push(gifts[i]);
51+
backtracking(i + 1, currentSet);
52+
currentSet.pop();
53+
}
54+
}
55+
56+
backtracking(0, []);
57+
58+
return results.sort((a, b) => a.length - b.length);
59+
}
60+
```
61+
62+
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.
63+
64+
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.
65+
66+
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).
67+
68+
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.
69+
70+
Finalmente, retornamos el array `results` ordenado por la longitud de cada combinación, de menor a mayor.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
function generateGiftSets(gifts) {
2+
const results = [];
3+
function backtracking(start, currentSet) {
4+
if (currentSet.length > 0) {
5+
results.push([...currentSet]);
6+
}
7+
8+
for (let i = start; i < gifts.length; i++) {
9+
currentSet.push(gifts[i]);
10+
backtracking(i + 1, currentSet);
11+
currentSet.pop();
12+
}
13+
}
14+
15+
backtracking(0, []);
16+
17+
return results.sort((a, b) => a.length - b.length);
18+
}
19+
module.exports = generateGiftSets;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
const generateGiftSets = require('./index');
2+
3+
describe('22 => Genera-combinaciones-de-regalos', () => {
4+
const TEST_CASES = [
5+
{
6+
input: ['car'],
7+
output: [['car']],
8+
},
9+
{
10+
input: ['car', 'doll', 'puzzle'],
11+
output: [
12+
['car'],
13+
['doll'],
14+
['puzzle'],
15+
['car', 'doll'],
16+
['car', 'puzzle'],
17+
['doll', 'puzzle'],
18+
['car', 'doll', 'puzzle'],
19+
],
20+
},
21+
{
22+
input: ['car', 'doll'],
23+
output: [['car'], ['doll'], ['car', 'doll']],
24+
},
25+
{
26+
input: ['apple', 'banana', 'cherry', 'date'],
27+
output: [
28+
['apple'],
29+
['banana'],
30+
['cherry'],
31+
['date'],
32+
['apple', 'banana'],
33+
['apple', 'cherry'],
34+
['apple', 'date'],
35+
['banana', 'cherry'],
36+
['banana', 'date'],
37+
['cherry', 'date'],
38+
['apple', 'banana', 'cherry'],
39+
['apple', 'banana', 'date'],
40+
['apple', 'cherry', 'date'],
41+
['banana', 'cherry', 'date'],
42+
['apple', 'banana', 'cherry', 'date'],
43+
],
44+
},
45+
{
46+
input: ['pen', 'notebook', 'eraser', 'pencil', 'marker'],
47+
output: [
48+
['pen'],
49+
['notebook'],
50+
['eraser'],
51+
['pencil'],
52+
['marker'],
53+
['pen', 'notebook'],
54+
['pen', 'eraser'],
55+
['pen', 'pencil'],
56+
['pen', 'marker'],
57+
['notebook', 'eraser'],
58+
['notebook', 'pencil'],
59+
['notebook', 'marker'],
60+
['eraser', 'pencil'],
61+
['eraser', 'marker'],
62+
['pencil', 'marker'],
63+
['pen', 'notebook', 'eraser'],
64+
['pen', 'notebook', 'pencil'],
65+
['pen', 'notebook', 'marker'],
66+
['pen', 'eraser', 'pencil'],
67+
['pen', 'eraser', 'marker'],
68+
['pen', 'pencil', 'marker'],
69+
['notebook', 'eraser', 'pencil'],
70+
['notebook', 'eraser', 'marker'],
71+
['notebook', 'pencil', 'marker'],
72+
['eraser', 'pencil', 'marker'],
73+
['pen', 'notebook', 'eraser', 'pencil'],
74+
['pen', 'notebook', 'eraser', 'marker'],
75+
['pen', 'notebook', 'pencil', 'marker'],
76+
['pen', 'eraser', 'pencil', 'marker'],
77+
['notebook', 'eraser', 'pencil', 'marker'],
78+
['pen', 'notebook', 'eraser', 'pencil', 'marker'],
79+
],
80+
},
81+
{
82+
input: [],
83+
output: [],
84+
},
85+
];
86+
87+
it('should return array type', () => {
88+
const result = generateGiftSets(['car']);
89+
expect(Array.isArray(result)).toBe(true);
90+
});
91+
92+
it.each(TEST_CASES)(
93+
'should return an array with $output.length elements',
94+
({ input, output }) => {
95+
const result = generateGiftSets(input);
96+
expect(result).toHaveLength(output.length);
97+
},
98+
);
99+
});

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ npm run test 'year'/'challenge'/index.test.js
7878
| 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) | ⭐⭐⭐⭐⭐ |
7979
| 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) | ⭐⭐⭐⭐⭐ |
8080
| 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) | ⭐⭐⭐⭐⭐ |
81+
| 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) | ⭐⭐⭐⭐⭐ |
8182

8283
Difficulties legend:
8384
🟢 Easy 🟡 Medium 🔴 Hard

0 commit comments

Comments
 (0)