Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d409db8

Browse files
✨ Add challenge-24 solution
1 parent f8839e0 commit d409db8

File tree

3 files changed

+460
-0
lines changed

3 files changed

+460
-0
lines changed
Lines changed: 393 additions & 0 deletions
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)

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /