Skip to content

Commit 5da1c18

Browse files
authored
Merge pull request #42 from marcode24/2024-24
✨ Add challenge-24 solution
2 parents f8839e0 + 4838453 commit 5da1c18

File tree

4 files changed

+461
-0
lines changed

4 files changed

+461
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,393 @@
1+
# Reto 24: Verifica-si-los-arboles-son-espejos-magicos
2+
3+
En el Polo Norte, los elfos tienen **dos árboles binarios mágicos que generan energía** 🌲🌲 para mantener encendida la estrella navideña ⭐️. Sin embargo, para que funcionen correctamente, los árboles deben estar en perfecta sincronía como espejos 🪞.
4+
5+
**Dos árboles binarios son espejos si:**
6+
7+
- Las raíces de ambos árboles tienen el mismo valor.
8+
- Cada nodo del primer árbol debe tener su correspondiente nodo en la posición opuesta en el segundo árbol.
9+
10+
Y el árbol se representa con tres propiedades `value`, `left` y `right`. Dentro de estas dos últimas va mostrando el resto de ramas (si es que tiene):
11+
12+
```js
13+
const tree = {
14+
value: '⭐️',
15+
left: {
16+
value: '🎅'
17+
// left: {...}
18+
// right: { ... }
19+
},
20+
right: {
21+
value: '🎁'
22+
// left: { ... }
23+
// right: { ... }
24+
}
25+
}
26+
```
27+
28+
Santa necesita tu ayuda para verificar si los árboles están sincronizados para que la estrella pueda seguir brillando. **Debes devolver un array** donde la **primera posición indica si los árboles están sincronizados** y **la segunda posición devuelve el valor de la raíz del primer árbol**.
29+
30+
```js
31+
const tree1 = {
32+
value: '🎄',
33+
left: { value: '' },
34+
right: { value: '🎅' }
35+
}
36+
37+
const tree2 = {
38+
value: '🎄',
39+
left: { value: '🎅' }
40+
right: { value: '' },
41+
}
42+
43+
isTreesSynchronized(tree1, tree2) // [true, '🎄']
44+
45+
/*
46+
tree1 tree2
47+
🎄 🎄
48+
/ \ / \
49+
⭐ 🎅 🎅 ⭐
50+
*/
51+
52+
const tree3 = {
53+
value: '🎄',
54+
left: { value: '🎅' },
55+
right: { value: '🎁' }
56+
}
57+
58+
isTreesSynchronized(tree1, tree3) // [false, '🎄']
59+
60+
const tree4 = {
61+
value: '🎄',
62+
left: { value: '' },
63+
right: { value: '🎅' }
64+
}
65+
66+
isTreesSynchronized(tree1, tree4) // [false, '🎄']
67+
68+
isTreesSynchronized(
69+
{ value: '🎅' },
70+
{ value: '🧑‍🎄' }
71+
) // [false, '🎅']
72+
```
73+
74+
## Mi solución explicada
75+
76+
```js
77+
function isTreesSynchronized(tree1, tree2) {
78+
function areMirrors(node1, node2) {
79+
if (!node1 && !node2) return true;
80+
if (!node1 || !node2 || node1.value !== node2.value) return false;
81+
82+
const leftAndRightAreMirrors = areMirrors(node1.left, node2.right);
83+
const rightAndLeftAreMirrors = areMirrors(node1.right, node2.left);
84+
85+
return leftAndRightAreMirrors && rightAndLeftAreMirrors;
86+
}
87+
88+
const synchronized = tree1.value === tree2.value && areMirrors(tree1, tree2);
89+
90+
return [synchronized, tree1.value];
91+
}
92+
```
93+
94+
Para resolver este reto, nuevamente utilizaremos la técnica de recursión.
95+
96+
Creamos una función `areMirrors` que recibe dos nodos y verifica si son espejos. Dentro tendremos las siguientes condiciones:
97+
98+
- Si ambos nodos son `null`, devolvemos `true`, ya que no hay nada que comparar.
99+
- Si uno de los dos nodos es `null`, o si los valores de los nodos son diferentes, devolvemos `false`. Ya que no cumplen con las condiciones para ser espejos.
100+
101+
Luego, comparamos los nodos izquierdos y derechos de ambos árboles. Para esto, llamamos a la función `areMirrors` con los nodos `node1.left` y `node2.right`, y con `node1.right` y `node2.left`. Si ambos son espejos, devolvemos `true`. De lo contrario, devolvemos `false`.
102+
103+
Seguidamente, comparamos si los árboles son sincronizados. Para esto, verificamos si los valores de las raíces son iguales y si los árboles son espejos.
104+
105+
Aquí utilizaremos un concepto de JavaScript llamado **short-circuit evaluation**. Si la primera condición es `false`, no se evaluará la segunda condición. Por lo tanto, si los valores de las raíces son diferentes, no se evaluará la función `areMirrors`.
106+
107+
Finalmente, devolvemos un array con la variable `synchronized` y el valor de la raíz del primer árbol.
108+
109+
**Veamos con un ejemplo donde opera el short-circuit evaluation:**
110+
111+
Supongamos que tenemos la siguiente entrada:
112+
113+
```js
114+
const tree1 = {
115+
value: '🎄',
116+
left: { value: '' },
117+
right: { value: '🎅' }
118+
}
119+
120+
const tree2 = {
121+
value: '🎁',
122+
left: { value: '🎅' }
123+
right: { value: '' },
124+
}
125+
```
126+
127+
En este caso, los valores de las raíces son diferentes (`🎄` y `🎁`). Por lo tanto, no se evaluará la función `areMirrors`.
128+
129+
```js
130+
const synchronized = tree1.value === tree2.value && areMirrors(tree1, tree2);
131+
132+
// const synchronized = '🎄' === '🎁' && areMirrors(tree1, tree2);
133+
// const synchronized = false && areMirrors(tree1, tree2);
134+
const synchronized = false;
135+
```
136+
137+
Como la primera condición es `false`, no se evaluará la segunda condición. Por lo tanto, la función `areMirrors` no se ejecutará. Procemos a devolver `[false, '🎄']`.
138+
139+
```js
140+
// return [synchronized, tree1.value];
141+
return [false, '🎄'];
142+
```
143+
144+
**Veamos un ejemplo mas complejo**:
145+
146+
Supongamos que tenemos la siguiente entrada:
147+
148+
```js
149+
const tree1 = {
150+
value: '🎄',
151+
left: { value: '' },
152+
right: { value: '🎅' }
153+
}
154+
155+
const tree2 = {
156+
value: '🎄',
157+
left: { value: '🎅' }
158+
right: { value: '' },
159+
}
160+
```
161+
162+
En este caso, los valores de las raíces son iguales (`🎄`). Por lo tanto, se evaluará la función `areMirrors`.
163+
164+
```js
165+
const synchronized = tree1.value === tree2.value && areMirrors(tree1, tree2);
166+
167+
// const synchronized = '🎄' === '🎄' && areMirrors(tree1, tree2
168+
// const synchronized = true && areMirrors(tree1, tree2);
169+
```
170+
171+
Como la primera condición es `true`, se evaluará la segunda condición. En este caso, la función `areMirrors` se ejecutará.
172+
173+
```js
174+
areMirrors(tree1, tree2);
175+
```
176+
177+
Dentro de la función `areMirrors`, se evaluarán los nodos izquierdos y derechos de ambos árboles.
178+
179+
Primero evaluamos la condición donde si ambos nodos son `null`, devolvemos `true`.
180+
181+
```js
182+
if (!node1 && !node2) return true;
183+
```
184+
185+
Como los nodos no son `null`, pasamos a la siguiente condición.
186+
187+
```js
188+
// en este momento tenemos los siguientes valores
189+
node1 = {
190+
value: '🎄',
191+
left: { value: '' },
192+
right: { value: '🎅' }
193+
}
194+
195+
node2 = {
196+
value: '🎄',
197+
left: { value: '🎅' }
198+
right: { value: '' },
199+
}
200+
```
201+
202+
```js
203+
if (!node1 || !node2 || node1.value !== node2.value) return false;
204+
// if (!node1 || !node2 || '🎄' !== '🎄') return false;
205+
// if (false || false || false) return false;
206+
// if (false) return false;
207+
208+
// como no se cumple la condición, pasamos a lo siguiente
209+
```
210+
211+
Como los nodos no son `null` y los valores son iguales, pasamos a evaluar los nodos izquierdos y derechos de ambos árboles.
212+
213+
```js
214+
const leftAndRightAreMirrors = areMirrors(node1.left, node2.right);
215+
const rightAndLeftAreMirrors = areMirrors(node1.right, node2.left);
216+
```
217+
218+
Enfoquémonos en el primer caso, donde evaluamos los nodos izquierdos.
219+
220+
```js
221+
const leftAndRightAreMirrors = areMirrors(node1.left, node2.right);
222+
223+
// const leftAndRightAreMirrors = areMirrors({ value: '⭐' }, { value: '⭐' });
224+
```
225+
226+
Volvemos a entrar a la función `areMirrors` y evaluamos los nodos.
227+
228+
```js
229+
if (!node1 && !node2) return true;
230+
// if (!{ value: '⭐' } && !{ value: '⭐' }) return true;
231+
// if (false && false) return true;
232+
// if (false) return true;
233+
234+
// como se cumple la condición pasamos a la siguiente
235+
```
236+
237+
Pasamos a la siguiente condición.
238+
239+
```js
240+
if (!node1 || !node2 || node1.value !== node2.value) return false;
241+
// if (false || false || '⭐' !== '⭐') return false;
242+
// if (false || false || false) return false;
243+
// if (false) return false;
244+
245+
// como no se cumple la condición, pasamos a lo siguiente
246+
```
247+
248+
Como los nodos no son `null` y los valores son iguales, pasamos a evaluar los nodos izquierdos y derechos.
249+
250+
```js
251+
const leftAndRightAreMirrors = areMirrors(node1.left, node2.right);
252+
const rightAndLeftAreMirrors = areMirrors(node1.right, node2.left);
253+
254+
// const leftAndRightAreMirrors = areMirrors(null, null);
255+
// const rightAndLeftAreMirrors = areMirrors(null, null);
256+
```
257+
258+
Aqui en ambos casos, los nodos son `null`, por lo que devolvemos `true`.
259+
260+
```js
261+
// llamado de leftAndRightAreMirrors
262+
263+
if (!node1 && !node2) return true;
264+
// if (!null && !null) return true;
265+
// if (true && true) return true;
266+
return true;
267+
```
268+
269+
```js
270+
// llamado de rightAndLeftAreMirrors
271+
272+
if (!node1 && !node2) return true;
273+
// if (!null && !null) return true;
274+
// if (true && true) return true;
275+
return true;
276+
```
277+
278+
Como ambos valores son `true`, devolvemos `true`.
279+
280+
```js
281+
return leftAndRightAreMirrors && rightAndLeftAreMirrors;
282+
// return true && true;
283+
return true;
284+
```
285+
286+
Ahora regresamos al primer llamado donde primero nos enfocamos en el `leftAndRightAreMirrors`. Ya evaluamos este llamado y nos devolvio `true`.
287+
288+
```js
289+
const leftAndRightAreMirrors = areMirrors({ value: '' }, { value: '' });
290+
const rightAndLeftAreMirrors = areMirrors({ value: '🎅' }, { value: '🎅' });
291+
```
292+
293+
Ahora evaluamos el segundo llamado.
294+
295+
```js
296+
const leftAndRightAreMirrors = true;
297+
const rightAndLeftAreMirrors = areMirrors({ value: '🎅' }, { value: '🎅' });
298+
```
299+
300+
Volvemos a entrar a la función `areMirrors` y evaluamos los nodos.
301+
302+
```js
303+
if (!node1 && !node2) return true;
304+
// if (!{ value: '🎅' } && !{ value: '🎅' }) return true;
305+
// if (false && false) return true;
306+
// if (false) return true;
307+
308+
// como se cumple la condición, devolvemos true
309+
```
310+
311+
Pasamos a la siguiente condición.
312+
313+
```js
314+
if (!node1 || !node2 || node1.value !== node2.value) return false;
315+
// if (false || false || '🎅' !== '🎅') return false;
316+
// if (false) return false;
317+
318+
// como no se cumple la condición, pasamos a lo siguiente
319+
```
320+
321+
Como los nodos no son `null` y los valos son iguales, pasamos a evaluar los nodos izquierdos y derechos.
322+
323+
```js
324+
const leftAndRightAreMirrors = areMirrors(node1.left, node2.right);
325+
const rightAndLeftAreMirrors = areMirrors(node1.right, node2.left);
326+
327+
// const leftAndRightAreMirrors = areMirrors(null, null);
328+
// const rightAndLeftAreMirrors = areMirrors(null, null);
329+
```
330+
331+
Aqui en ambos casos, los nodos son `null`, por lo que devolvemos `true`.
332+
333+
```js
334+
// llamado de leftAndRightAreMirrors
335+
336+
if (!node1 && !node2) return true;
337+
// if (!null && !null) return true;
338+
// if (true && true) return true;
339+
return true;
340+
```
341+
342+
```js
343+
// llamado de rightAndLeftAreMirrors
344+
345+
if (!node1 && !node2) return true;
346+
// if (!null && !null) return true;
347+
// if (true && true) return true;
348+
return true;
349+
```
350+
351+
Como ambos valores son `true`, devolvemos `true`.
352+
353+
```js
354+
return leftAndRightAreMirrors && rightAndLeftAreMirrors;
355+
// return true && true;
356+
return true;
357+
```
358+
359+
Ahora regresamos al primer llamado donde primero nos enfocamos en el `rightAndLeftAreMirrors`. Ya evaluamos este llamado y nos devolvio `true`.
360+
361+
```js
362+
// const leftAndRightAreMirrors = areMirrors({ value: '⭐' }, { value: '⭐' });
363+
// const rightAndLeftAreMirrors = areMirrors({ value: '🎅' }, { value: '🎅' });
364+
365+
const leftAndRightAreMirrors = true;
366+
const rightAndLeftAreMirrors = true;
367+
```
368+
369+
Evaluamos si ambos valores son `true`.
370+
371+
```js
372+
return leftAndRightAreMirrors && rightAndLeftAreMirrors;
373+
// return true && true;
374+
return true;
375+
```
376+
377+
Como ambos valores son `true`, devolvemos `true`. Entonces el resultado de la función `areMirrors` es `true`.
378+
379+
```js
380+
const synchronized = tree1.value === tree2.value && areMirrors(tree1, tree2);
381+
// const synchronized = '🎄' === '🎄' && true;
382+
// const synchronized = true && true;
383+
const synchronized = true;
384+
```
385+
386+
Finalmente, devolvemos `[true, '🎄']`.
387+
388+
```js
389+
return [synchronized, tree1.value];
390+
// return [true, '🎄'];
391+
```
392+
393+
Y con esto hemos terminado de resolver el reto 🎉.

0 commit comments

Comments
 (0)