Skip to content

Commit 32b628e

Browse files
authored
Merge pull request #40 from marcode24/2024-18
✨ Add challenge-18 solution
2 parents 9de4759 + a3433b2 commit 32b628e

File tree

4 files changed

+272
-0
lines changed

4 files changed

+272
-0
lines changed

Diff for: 2024/18-la-agenda-magica-de-santa/README.md

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# Reto 18: La-agenda-magica-de-santa
2+
3+
Santa Claus tiene una agenda mágica 📇 donde guarda las direcciones de los niños para entregar los regalos. El problema: **la información de la agenda está mezclada y malformateada**. Las líneas contienen un número de teléfono mágico, el nombre de un niño y su dirección, pero todo está rodeado de caracteres extraños.
4+
5+
Santa necesita tu ayuda para encontrar información específica de la agenda. Escribe una función que, **dado el contenido de la agenda y un número de teléfono, devuelva el nombre del niño y su dirección.**
6+
7+
Ten en cuenta que en la agenda:
8+
9+
- Los números de teléfono están formateados como +X-YYY-YYY-YYY (donde X es uno o dos dígitos, e Y es un dígito).
10+
- El nombre de cada niño está siempre entre < y >
11+
12+
La idea es que escribas una funcióna que, pasándole el teléfono completo o una parte, devuelva el nombre y dirección del niño. **Si no encuentra nada o hay más de un resultado**, debes devolver `null`.
13+
14+
```js
15+
const agenda = `+34-600-123-456 Calle Gran Via 12 <Juan Perez>
16+
Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654
17+
<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York`
18+
19+
findInAgenda(agenda, '34-600-123-456')
20+
// { name: "Juan Perez", address: "Calle Gran Via 12" }
21+
22+
findInAgenda(agenda, '600-987')
23+
// { name: "Maria Gomez", address: "Plaza Mayor 45 Madrid 28013" }
24+
25+
findInAgenda(agenda, '111')
26+
// null
27+
// Explicación: No hay resultados
28+
29+
findInAgenda(agenda, '1')
30+
// null
31+
// Explicación: Demasiados resultados
32+
```
33+
34+
## Mi solución explicada
35+
36+
```js
37+
function findInAgenda(agenda, phone) {
38+
const kidsList = agenda.split('\n');
39+
const foundKids = kidsList.filter((kid) => kid.includes(phone));
40+
41+
const matchingCount = foundKids?.length;
42+
43+
if (matchingCount === 1) {
44+
const [firstKid] = foundKids;
45+
const name = firstKid.split('<')[1].split('>')[0];
46+
const address = firstKid
47+
.split(' ')
48+
.slice(1, -1)
49+
.join(' ')
50+
.split('<')[0]
51+
.trim();
52+
53+
return { name, address };
54+
}
55+
56+
return null;
57+
}
58+
```
59+
60+
Para resolver este reto, primero dividí la agenda en una lista de niños por cada salto de línea.
61+
62+
Luego, filtré la lista de niños para encontrar aquellos que contienen el número de teléfono que se busca y guardé el resultado en `foundKids`.
63+
64+
Después, conté cuántos niños coinciden con el número de teléfono buscado y guardé el resultado en `matchingCount`.
65+
66+
Em este caso si no hay resultados o hay más de uno, devuelvo `null` porque como dice el enunciado, si no hay resultados o hay más de un resultado, debes devolver `null`.
67+
68+
Si hay un solo resultado, extraigo el nombre y la dirección del niño y los devuelvo en un objeto.
69+
70+
Para obtener el nombre del niño, busco el texto que está entre los caracteres `<` y `>`.
71+
72+
Para obtener la dirección del niño, elimino el número de teléfono y el nombre del niño de la cadena, y luego elimino los espacios en blanco al principio y al final de la cadena.
73+
74+
Finalmente, devuelvo un objeto con el nombre y la dirección del niño.
75+
76+
**Veamos con un ejemplo cómo funciona**:
77+
78+
Supongamos que tenemos la siguiente agenda:
79+
80+
```js
81+
const agenda = `+34-600-123-456 Calle Gran Via 12 <Juan Perez>
82+
Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654
83+
<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York`
84+
```
85+
86+
y queremos buscar el número de teléfono `34-600-123-456`.
87+
88+
Primero, dividimos la agenda en una lista de niños:
89+
90+
```js
91+
const kidsList = agenda.split('\n');
92+
93+
// kidsList = [
94+
// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>',
95+
// 'Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654',
96+
// '<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'
97+
// ]
98+
```
99+
100+
Despues filtramos la lista de niños para encontrar aquellos que contienen el número de teléfono que buscamos:
101+
102+
Al utilizar el método `filter` con la condición `kid.includes('34-600-123-456')`, obtenemos un nuevo array con los niños que contienen el número de teléfono buscado. Ya que la cadena `'+34-600-123-456 Calle Gran Via 12 <Juan Perez>'` contiene el número de teléfono `34-600-123-456`.
103+
104+
```js
105+
const foundKids = kidsList.filter((kid) => kid.includes('34-600-123-456'));
106+
107+
// foundKids = [
108+
// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>'
109+
// ]
110+
```
111+
112+
Luego, contamos cuántos niños coinciden con el número de teléfono buscado:
113+
114+
```js
115+
const matchingCount = foundKids?.length;
116+
const matchingCount = 1;
117+
```
118+
119+
Ahora validamos la condición que nos dice que si no hay resultados o hay más de uno, debemos devolver `null`. En este caso, como hay un solo resultado, extraemos el nombre y la dirección del niño y los devolvemos en un objeto:
120+
121+
```js
122+
const [firstKid] = foundKids;
123+
const name = firstKid.split('<')[1].split('>')[0];
124+
125+
// const name = '+34-600-123-456 Calle Gran Via 12 <Juan Perez>'.split('<')[1].split('>')[0];
126+
// const name = ['+34-600-123-456 Calle Gran Via 12 ', 'Juan Perez>'][1].split('>')[0];
127+
// const name = ['Juan Perez>'].split('>')[0];
128+
// const name = ['Juan Perez', ''][0];
129+
const name = 'Juan Perez';
130+
131+
const address = firstKid
132+
.split(' ')
133+
.slice(1, -1)
134+
.join(' ')
135+
.split('<')[0]
136+
.trim();
137+
138+
// const address = '+34-600-123-456 Calle Gran Via 12 <Juan Perez>'.split(' ').slice(1, -1).join(' ').split('<')[0].trim();
139+
// const address = ['+34-600-123-456', 'Calle', 'Gran', 'Via', '12', '<Juan', 'Perez>'].slice(1, -1).join(' ').split('<')[0].trim();
140+
// const address = ['Calle', 'Gran', 'Via', '12', '<Juan'].join(' ').split('<')[0].trim();
141+
// const address = 'Calle Gran Via 12 <Juan'.split('<')[0].trim();
142+
// const address = ['Calle Gran Via 12 ', 'Juan'][0].trim();
143+
// const address = 'Calle Gran Via 12 '.trim();
144+
const address = 'Calle Gran Via 12';
145+
146+
return { name, address };
147+
148+
// { name: "Juan Perez", address: "Calle Gran Via 12" }
149+
```
150+
151+
Finalmente, devolvemos un objeto con el nombre y la dirección del niño.
152+
153+
**Ahora veamos un caso en el que pueden haber más de un resultado**:
154+
155+
Supongamos que queremos buscar el número de teléfono `1`.
156+
157+
Primero, dividimos la agenda en una lista de niños:
158+
159+
```js
160+
const kidsList = agenda.split('\n');
161+
162+
// kidsList = [
163+
// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>',
164+
// 'Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654',
165+
// '<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'
166+
// ]
167+
```
168+
169+
Despues filtramos la lista de niños para encontrar aquellos que contienen el número de teléfono que buscamos:
170+
171+
Al utilizar el método `filter` con la condición `kid.includes('1')`, obtenemos un nuevo array con los niños que contienen el número de teléfono buscado. Ya que las cadenas `'<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'` y `'<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'` contienen el número de teléfono `1`.
172+
173+
```js
174+
const foundKids = kidsList.filter((kid) => kid.includes('1'));
175+
176+
// kidsFound: [
177+
// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>',
178+
// 'Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654',
179+
// '<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'
180+
// ]
181+
```
182+
183+
Luego, contamos cuántos niños coinciden con el número de teléfono buscado:
184+
185+
```js
186+
const matchingCount = foundKids?.length;
187+
const matchingCount = 3;
188+
```
189+
190+
Ahora validamos la condición que nos dice que si no hay resultados o hay más de uno, debemos devolver `null`. En este caso, como hay más de un resultado, devolvemos `null`.
191+
192+
```js
193+
if (matchingCount === 1) {...}
194+
if (3 === 1) {...}
195+
if (false) {...} // No se cumple la condición
196+
197+
return null;
198+
```
199+
200+
Finalmente, devolvemos `null` porque hay más de un resultado.
201+
202+
```js
203+
return null;
204+
```
205+
206+
Y eso es todo. Esa es la solución al reto 🎉

Diff for: 2024/18-la-agenda-magica-de-santa/index.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function findInAgenda(agenda, phone) {
2+
const kidsList = agenda.split('\n');
3+
const foundKids = kidsList.filter((kid) => kid.includes(phone));
4+
5+
const matchingCount = foundKids?.length;
6+
7+
if (matchingCount === 1) {
8+
const [firstKid] = foundKids;
9+
const name = firstKid.split('<')[1].split('>')[0];
10+
const address = firstKid
11+
.split(' ')
12+
.slice(1, -1)
13+
.join(' ')
14+
.split('<')[0]
15+
.trim();
16+
17+
return { name, address };
18+
}
19+
20+
return null;
21+
}
22+
23+
module.exports = findInAgenda;

Diff for: 2024/18-la-agenda-magica-de-santa/index.test.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const findInAgenda = require('./index');
2+
3+
describe('18 => La-agenda-magica-de-santa', () => {
4+
const agenda = `+34-600-123-456 Calle Gran Via 12 <Juan Perez>
5+
Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654
6+
<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York`;
7+
8+
const testCases = [
9+
{
10+
input: [agenda, '34-600-123-456'],
11+
output: { name: 'Juan Perez', address: 'Calle Gran Via 12' },
12+
},
13+
{
14+
input: [agenda, '600-987'],
15+
output: {
16+
name: 'Maria Gomez',
17+
address: 'Mayor 45 Madrid 28013',
18+
},
19+
},
20+
{
21+
input: [agenda, '111'],
22+
output: null,
23+
},
24+
{
25+
input: [agenda, '1'],
26+
output: null,
27+
},
28+
];
29+
30+
it('should return an object', () => {
31+
const result = findInAgenda(agenda, '34-600-123-456');
32+
expect(typeof result).toBe('object');
33+
});
34+
35+
it.each(testCases)(
36+
'should return the correct name and address',
37+
(testCase) => {
38+
const result = findInAgenda(...testCase.input);
39+
expect(result).toEqual(testCase.output);
40+
},
41+
);
42+
});

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ npm run test 'year'/'challenge'/index.test.js
7676
| 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) | ⭐⭐⭐⭐⭐ |
7777
| 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) | ⭐⭐⭐⭐⭐ |
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) | ⭐⭐⭐⭐⭐ |
79+
| 18 | [💾 La agenda mágica de santa](https://adventjs.dev/es/challenges/2024/18) | 🔴 | [here](./2024/18-la-agenda-magica-de-santa/index.js) | [here](./2024/18-la-agenda-magica-de-santa/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ |
7980
| 19 | [📦 Apila cajas mágicas para repartir regalos](https://adventjs.dev/es/challenges/2024/19) | 🔴 | [here](./2024/19-apila-cajas-magicas-para-repartir-regalos/index.js) | [here](./2024/19-apila-cajas-magicas-para-repartir-regalos/README.md#mi-solución-explicada) | ⭐⭐⭐⭐⭐ |
8081
| 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) | ⭐⭐⭐⭐⭐ |
8182
| 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) | ⭐⭐⭐⭐⭐ |

0 commit comments

Comments
 (0)