Skip to content

Commit 8cd6714

Browse files
committed
✨ Add challenge-05 solution
1 parent 4d4d4ed commit 8cd6714

File tree

3 files changed

+225
-0
lines changed

3 files changed

+225
-0
lines changed

2024/05-emparejando-botas/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Reto 05: Emparejando-botas
2+
3+
**Los elfos 🧝🧝‍♂️ de Santa Claus** han encontrado un montón de botas mágicas desordenadas en el taller. Cada bota se describe por dos valores:
4+
5+
- type indica si es una bota izquierda (I) o derecha (R).
6+
- size indica el tamaño de la bota.
7+
8+
Tu tarea es ayudar a los elfos a emparejar todas las botas del mismo tamaño que tengan izquierda y derecha. Para ello, debes devolver una lista con los pares disponibles después de emparejar las botas.
9+
10+
¡Ten en cuenta que **puedes tener más de una zapatilla emparejada del mismo tamaño!**
11+
12+
```js
13+
const shoes = [
14+
{ type: 'I', size: 38 },
15+
{ type: 'R', size: 38 },
16+
{ type: 'R', size: 42 },
17+
{ type: 'I', size: 41 },
18+
{ type: 'I', size: 42 }
19+
]
20+
21+
organizeShoes(shoes)
22+
// [38, 42]
23+
24+
const shoes2 = [
25+
{ type: 'I', size: 38 },
26+
{ type: 'R', size: 38 },
27+
{ type: 'I', size: 38 },
28+
{ type: 'I', size: 38 },
29+
{ type: 'R', size: 38 }
30+
]
31+
// [38, 38]
32+
33+
const shoes3 = [
34+
{ type: 'I', size: 38 },
35+
{ type: 'R', size: 36 },
36+
{ type: 'R', size: 42 },
37+
{ type: 'I', size: 41 },
38+
{ type: 'I', size: 43 }
39+
]
40+
41+
organizeShoes(shoes3)
42+
// []
43+
```
44+
45+
## Mi solución explicada
46+
47+
```js
48+
function organizeShoes(shoes) {
49+
const sizeCount = new Map();
50+
51+
for (const { type, size } of shoes) {
52+
const counts = sizeCount.get(size) || { I: 0, R: 0 };
53+
counts[type]++;
54+
sizeCount.set(size, counts);
55+
}
56+
57+
return Array.from(sizeCount.entries()).flatMap(([size, { I, R }]) =>
58+
Array(Math.min(I, R)).fill(size),
59+
);
60+
}
61+
```
62+
63+
Para resolver este problema, primero creamos un mapa `sizeCount` para almacenar el recuento de botas de cada tamaño. Esto nos permitirá contar cuántas botas izquierdas y derechas hay para cada tamaño.
64+
65+
```js
66+
const sizeCount = new Map();
67+
```
68+
69+
Luego, recorremos todas las botas y actualizamos el recuento de botas de cada tamaño en el mapa `sizeCount`.
70+
71+
```js
72+
for (const { type, size } of shoes) {
73+
const counts = sizeCount.get(size) || { I: 0, R: 0 };
74+
counts[type]++;
75+
sizeCount.set(size, counts);
76+
}
77+
```
78+
79+
Denotamos el recuento de botas izquierdas y derechas para cada tamaño con un objeto `{ I: 0, R: 0 }`. Luego, incrementamos el recuento correspondiente según el tipo de bota. Finalmente, actualizamos el recuento en el mapa `sizeCount`.
80+
81+
Si nuestra entrada es la siguiente:
82+
83+
```js
84+
const shoes = [
85+
{ type: 'I', size: 38 },
86+
{ type: 'R', size: 38 },
87+
{ type: 'R', size: 42 },
88+
{ type: 'I', size: 41 },
89+
{ type: 'I', size: 42 }
90+
];
91+
```
92+
93+
El mapa `sizeCount` se verá así:
94+
95+
```js
96+
Map {
97+
38 => { I: 1, R: 1 },
98+
42 => { I: 1, R: 1 },
99+
41 => { I: 1, R: 0 }
100+
}
101+
```
102+
103+
Finalmente, devolvemos un array de pares de botas emparejadas. Para cada entrada en el mapa `sizeCount`, creamos un array de tamaño igual al mínimo de botas izquierdas y derechas para ese tamaño. Luego, llenamos el array con el tamaño de la bota y lo aplanamos.
104+
105+
```js
106+
return Array.from(sizeCount.entries()).flatMap(([size, { I, R }]) =>
107+
Array(Math.min(I, R)).fill(size),
108+
);
109+
```
110+
111+
Desmenuzando el código, tenemos que `sizeCount.entries()` nos devolveria lo siguiente:
112+
113+
```js
114+
[
115+
[38, { I: 1, R: 1 }],
116+
[42, { I: 1, R: 1 }],
117+
[41, { I: 1, R: 0 }]
118+
]
119+
```
120+
121+
Pasandolo por `flatMap`, tenemos que son 3 iteraciones. Para la primera iteración, tenemos:
122+
123+
```js
124+
size = 38
125+
{ I: 1, R: 1 }
126+
```
127+
128+
Por lo que `Math.min(I, R)` nos devolvería `1`, y `Array(1).fill(size)` nos devolvería `[38]`. Para la segunda iteración, tenemos:
129+
130+
```js
131+
size = 42
132+
{ I: 1, R: 1 }
133+
```
134+
135+
Por lo que `Math.min(I, R)` nos devolvería `1`, y `Array(1).fill(size)` nos devolvería `[42]`. Para la tercera iteración, tenemos:
136+
137+
```js
138+
size = 41
139+
{ I: 1, R: 0 }
140+
```
141+
142+
Por lo que `Math.min(I, R)` nos devolvería `0`, y `Array(0).fill(size)` nos devolvería `[]`.
143+
144+
Fuera de `flatMap`, tenemos `[ [38], [42], [] ]`. Al aplanar el array, obtenemos `[38, 42]`, que es el resultado correcto.

2024/05-emparejando-botas/index.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* eslint-disable function-paren-newline */
2+
/* eslint-disable implicit-arrow-linebreak */
3+
/* eslint-disable no-restricted-syntax */
4+
function organizeShoes(shoes) {
5+
const sizeCount = new Map();
6+
7+
for (const { type, size } of shoes) {
8+
const counts = sizeCount.get(size) || { I: 0, R: 0 };
9+
counts[type]++;
10+
sizeCount.set(size, counts);
11+
}
12+
13+
return Array.from(sizeCount.entries()).flatMap(([size, { I, R }]) =>
14+
Array(Math.min(I, R)).fill(size),
15+
);
16+
}
17+
18+
module.exports = organizeShoes;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const organizeShoes = require('./index');
2+
3+
describe('05 => Emparejando-botas', () => {
4+
const testCases = [
5+
{
6+
input: [
7+
{ type: 'I', size: 38 },
8+
{ type: 'R', size: 38 },
9+
{ type: 'R', size: 42 },
10+
{ type: 'I', size: 41 },
11+
{ type: 'I', size: 42 },
12+
],
13+
output: [38, 42],
14+
},
15+
{
16+
input: [
17+
{ type: 'I', size: 38 },
18+
{ type: 'R', size: 38 },
19+
{ type: 'I', size: 38 },
20+
{ type: 'I', size: 38 },
21+
{ type: 'R', size: 38 },
22+
],
23+
output: [38, 38],
24+
},
25+
{
26+
input: [
27+
{ type: 'I', size: 38 },
28+
{ type: 'R', size: 36 },
29+
{ type: 'R', size: 42 },
30+
{ type: 'I', size: 41 },
31+
{ type: 'I', size: 42 },
32+
],
33+
output: [42],
34+
},
35+
{
36+
input: [
37+
{ type: 'I', size: 40 },
38+
{ type: 'R', size: 40 },
39+
{ type: 'I', size: 40 },
40+
{ type: 'R', size: 40 },
41+
],
42+
output: [40, 40],
43+
},
44+
{
45+
input: [
46+
{ type: 'I', size: 39 },
47+
{ type: 'R', size: 39 },
48+
{ type: 'R', size: 39 },
49+
],
50+
output: [39],
51+
},
52+
];
53+
54+
it('should return an array', () => {
55+
const result = organizeShoes([]);
56+
expect(result).toBeInstanceOf(Array);
57+
});
58+
59+
it.each(testCases)('should return $output', ({ input, output }) => {
60+
const result = organizeShoes(input);
61+
expect(result).toEqual(output);
62+
});
63+
});

0 commit comments

Comments
 (0)