Skip to content

Commit 29e7d2a

Browse files
authored
Merge pull request #32 from marcode24/2024-14
✨ Add challenge-14 solution
2 parents 6f2a492 + 3da0a4c commit 29e7d2a

File tree

4 files changed

+274
-0
lines changed

4 files changed

+274
-0
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Reto 14: Acomodando-los-renos
2+
3+
Los renos necesitan moverse para ocupar los establos, **pero no puede haber más de un reno por establo**. Además, para que los renos estén cómodos, debemos minimizar la distancia total que recorren para acomodarse.
4+
5+
Tenemos dos parámetros:
6+
7+
- `reindeer`: Un array de enteros que representan las posiciones de los renos.
8+
- `stables`: Un array de enteros que representan las posiciones de los establos.
9+
10+
Hay que mover cada reno, desde su posición actual, hasta un establo. Pero hay que tener en cuenta **que sólo puede haber un reno por establo**.
11+
12+
Tu tarea es calcular el **mínimo número de movimientos necesarios** para que todos los renos acaben en un establo.
13+
14+
*Nota:* Ten en cuenta que **el array de establos siempre tendrá el mismo tamaño que el array de renos y que siempre los establos serán únicos.**
15+
16+
Ejemplo
17+
18+
```js
19+
minMovesToStables([2, 6, 9], [3, 8, 5]) // -> 3
20+
// Explicación:
21+
// Renos en posiciones: 2, 6, 9
22+
// Establos en posiciones: 3, 8, 5
23+
// 1er reno: se mueve de la posición 2 al establo en la posición 3 (1 movimiento).
24+
// 2do reno: se mueve de la posición 6 al establo en la posición 5 (1 movimiento)
25+
// 3er reno: se mueve de la posición 9 al establo en la posición 8 (1 movimiento).
26+
// Total de movimientos: 1 + 1 + 1 = 3 movimientos
27+
28+
minMovesToStables([1, 1, 3], [1, 8, 4])
29+
// Explicación:
30+
// Renos en posiciones: 1, 1, 3
31+
// Establos en posiciones: 1, 8, 4
32+
// 1er reno: no se mueve (0 movimientos)
33+
// 2do reno: se mueve de la posición 1 al establo en la posición 4 (3 movimientos)
34+
// 3er reno: se mueve de la posición 3 al establo en la posición 8 (5 movimientos)
35+
// Total de movimientos: 0 + 3 + 5 = 8 movimientos
36+
```
37+
38+
## Mi solución explicada
39+
40+
```js
41+
function minMovesToStables(reindeer, stables) {
42+
reindeer.sort();
43+
stables.sort();
44+
45+
return reindeer.reduce((totalMoves, currentReindeerPosition, index) => {
46+
const currentStablePosition = stables[index];
47+
const distance = Math.abs(currentReindeerPosition - currentStablePosition);
48+
return totalMoves + distance;
49+
}, 0);
50+
}
51+
```
52+
53+
Para poder resolver este reto, hay que hallar la forma de minimizar la distancia total que recorren los renos para acomodarse en los establos.
54+
55+
Para ello, primero ordenamos los arrays de renos y establos de menor a mayor. Una vez hecho esto, recorremos el array de renos y, por cada reno, calculamos la distancia que tiene que recorrer para llegar al establo correspondiente.
56+
57+
En este caso, dado que trabajamos con un array puramente numérico, no es necesario proporcionar una función de comparación al método sort, ya que JavaScript detecta que los elementos son números y aplica una comparación implícita para ordenarlos correctamente en orden ascendente.
58+
59+
Por lo tanto, incluso para valores como `[1, 10, 2]`, `sort()` producirá el resultado correcto `[1, 2, 10]`.
60+
61+
Sin embargo, si el array contiene cadenas de texto numéricas o es mixto (números y cadenas), es recomendable usar una función de comparación explícita `(a, b) => a - b` para garantizar un comportamiento consistente en todos los casos.
62+
63+
Por último, sumamos todas las distancias calculadas y devolvemos el total de movimientos necesarios para que todos los renos acaben en un establo.
64+
65+
**Veamos un ejemplo:**
66+
67+
```js
68+
minMovesToStables([2, 6, 9], [3, 8, 5]) // -> 3
69+
```
70+
71+
Supongamos que tenemos la siguiente entrada, donde los renos están en las posiciones `2, 6, 9` y los establos en las posiciones `3, 8, 5`. Si todo sale bien, el resultado debería ser `3`.
72+
73+
Primero, ordenamos los arrays de menor a mayor.
74+
75+
Hay que tener en cuenta que no es necesario asignar los valores ordenados a nuevas variables, ya que los arrays originales se ordenan de forma mutativa. Es decir, los arrays originales se modifican directamente.
76+
77+
```js
78+
// reindeer.sort();
79+
// [2, 6, 9].sort();
80+
[2, 6, 9];
81+
82+
// stables.sort();
83+
// [3, 8, 5].sort();
84+
[3, 5, 8]
85+
```
86+
87+
Para este momento, los arrays tienen la siguiente forma:
88+
89+
```js
90+
reindeer = [2, 6, 9];
91+
stables = [3, 5, 8];
92+
```
93+
94+
Luego, recorremos el array de renos y calculamos la distancia que tiene que recorrer cada reno para llegar al establo correspondiente. Aquí utilizamos el método `reduce` para acumular la suma de las distancias iterando sobre los renos.
95+
96+
```js
97+
return reindeer.reduce((totalMoves, currentReindeerPosition, index) => {
98+
...
99+
}, 0);
100+
```
101+
102+
Nuestra función de reducción recibe 2 parametros:
103+
104+
Primero, una función que toma 3 argumentos: `totalMoves`, `currentReindeerPosition` e `index`.
105+
106+
- `totalMoves` es el acumulador que mantiene la suma total de las distancias recorridas por los renos
107+
- `currentReindeerPosition` es la posición actual del reno en el array. También pasamos un tercer parámetro opcional
108+
- `index` nos permitirá acceder a la posición actual del reno en el array. Este índice se utiliza para acceder a la posición correspondiente en el array de establos.
109+
110+
Segundo, un valor inicial para `totalMoves`, que en este caso es `0`. Este valor inicial es importante para que la función de reducción pueda comenzar a acumular la suma de las distancias desde el primer reno.
111+
112+
Para nuestra primera iteración, tenemos lo siguiente:
113+
114+
El valor de nuestros parámetros es:
115+
116+
```js
117+
totalMoves = 0
118+
currentReindeerPosition = 2
119+
index = 0
120+
```
121+
122+
Calculamos la distancia entre la posición actual del reno y la posición del establo correspondiente.
123+
124+
```js
125+
// const currentStablePosition = stables[index];
126+
// const currentStablePosition = [3, 5, 8][0];
127+
const currentStablePosition = 3;
128+
129+
// const distance = Math.abs(currentReindeerPosition - currentStablePosition);
130+
// const distance = Math.abs(2 - 3);
131+
// const distance = Math.abs(-1);
132+
const distance = 1;
133+
134+
// return totalMoves + distance;
135+
// return 0 + 1;
136+
return 1;
137+
```
138+
139+
Para la segunda iteración, tenemos lo siguiente:
140+
141+
```js
142+
totalMoves = 1
143+
currentReindeerPosition = 6
144+
index = 1
145+
```
146+
147+
Calculamos la distancia entre la posición actual del reno y la posición del establo correspondiente.
148+
149+
```js
150+
// const currentStablePosition = stables[index];
151+
// const currentStablePosition = [3, 5, 8][1];
152+
const currentStablePosition = 5;
153+
154+
// const distance = Math.abs(currentReindeerPosition - currentStablePosition);
155+
// const distance = Math.abs(6 - 5);
156+
// const distance = Math.abs(1);
157+
const distance = 1;
158+
159+
// return totalMoves + distance;
160+
// return 1 + 1;
161+
return 2;
162+
```
163+
164+
Para la tercera iteración, tenemos lo siguiente:
165+
166+
```js
167+
totalMoves = 2
168+
currentReindeerPosition = 9
169+
index = 2
170+
```
171+
172+
Calculamos la distancia entre la posición actual del reno y la posición del establo correspondiente.
173+
174+
```js
175+
// const currentStablePosition = stables[index];
176+
// const currentStablePosition = [3, 5, 8][2];
177+
const currentStablePosition = 8;
178+
179+
// const distance = Math.abs(currentReindeerPosition - currentStablePosition);
180+
// const distance = Math.abs(9 - 8);
181+
// const distance = Math.abs(1);
182+
const distance = 1;
183+
184+
// return totalMoves + distance;
185+
// return 2 + 1;
186+
return 3;
187+
```
188+
189+
Como son 3 iteraciones, devolvemos directamente el total de movimientos necesarios para que todos los renos acaben en un establo.
190+
191+
```js
192+
// return reindeer.reduce((totalMoves, currentReindeerPosition, index) => {...}, 0);
193+
// return [2, 6, 9].reduce((0, 2, 0) => {...}, 0);
194+
// return [2, 6, 9].reduce((1, 6, 1) => {...}, 0);
195+
// return [2, 6, 9].reduce((2, 2, 9) => {...}, 0);
196+
return 3;
197+
```
198+
199+
Por lo tanto, el resultado final es `3`, que es el mínimo número de movimientos necesarios para que todos los renos acaben en un establo.
200+
201+
**Nota:** Siempre es importante tener en cuenta que, en este caso, los arrays de renos y establos tienen la misma longitud y que los establos son únicos. Si no se cumple esta condición, el resultado podría no ser el esperado.
202+
203+
Asi es como resolvemos el reto de hoy 🎉

2024/14-acomodando-los-renos/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function minMovesToStables(reindeer, stables) {
2+
reindeer.sort();
3+
stables.sort();
4+
5+
return reindeer.reduce((totalMoves, currentReindeerPosition, index) => {
6+
const currentStablePosition = stables[index];
7+
const distance = Math.abs(currentReindeerPosition - currentStablePosition);
8+
return totalMoves + distance;
9+
}, 0);
10+
}
11+
12+
module.exports = minMovesToStables;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const minMovesToStables = require('./index');
2+
3+
describe('14 => Acomodando-los-renos', () => {
4+
const TEST_CASES = [
5+
{
6+
input: [
7+
[2, 6, 9],
8+
[3, 8, 5],
9+
],
10+
output: 3,
11+
},
12+
{
13+
input: [
14+
[1, 1, 3],
15+
[1, 4, 8],
16+
],
17+
output: 8,
18+
},
19+
{
20+
input: [
21+
[5, 15, 10],
22+
[8, 18, 12],
23+
],
24+
output: 8,
25+
},
26+
{
27+
input: [
28+
[30, 1, 2],
29+
[1, 2, 30],
30+
],
31+
output: 0,
32+
},
33+
{
34+
input: [
35+
[30, 20, 10],
36+
[35, 25, 15],
37+
],
38+
output: 15,
39+
},
40+
{
41+
input: [
42+
[100, 1],
43+
[50, 75],
44+
],
45+
output: 74,
46+
},
47+
];
48+
49+
it('should return number type', () => {
50+
const testCase = TEST_CASES[0];
51+
const result = minMovesToStables(...testCase.input);
52+
expect(typeof result).toBe('number');
53+
});
54+
55+
it.each(TEST_CASES)('should return $output', ({ input, output }) => {
56+
expect(minMovesToStables(...input)).toBe(output);
57+
});
58+
});

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ npm run test 'year'/'challenge'/index.test.js
7272
| 11 | [📂 Nombres de archivos codificados](https://adventjs.dev/es/challenges/2024/11) | 🟢 | [here](./2024/11-nombres-de-archivos-codificados/index.js) | ⭐⭐⭐⭐⭐ |
7373
| 12 | [🎄 ¿Cuánto cuesta el árbol?](https://adventjs.dev/es/challenges/2024/12) | 🟢 | [here](./2024/12-cuanto-cuesta-el-arbol/index.js) | ⭐⭐⭐⭐⭐ |
7474
| 13 | [🤖 ¿El robot está de vuelta?](https://adventjs.dev/es/challenges/2024/13) | 🔴 | [here](./2024/13-el-robot-esta-de-vuelta/index.js) | ⭐⭐⭐⭐⭐ |
75+
| 14 | [🦌 Acomodando los renos](https://adventjs.dev/es/challenges/2024/14) | 🟢 | [here](./2024/14-acomodando-los-renos/index.js) | ⭐⭐⭐⭐⭐ |
7576

7677
Difficulties legend:
7778
🟢 Easy 🟡 Medium 🔴 Hard

0 commit comments

Comments
 (0)