Skip to content

Commit 4d4d4ed

Browse files
authored
Merge pull request #22 from marcode24/2024-04
✨ Add challenge-04 solution
2 parents 724eaa1 + 039983b commit 4d4d4ed

File tree

4 files changed

+244
-0
lines changed

4 files changed

+244
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Reto 04: Decorando-el-arbol-de-navidad
2+
3+
**¡Es hora de poner el árbol de Navidad en casa!** 🎄 Pero este año queremos que sea especial. Vamos a crear una función que recibe la altura del árbol (un entero positivo entre 1 y 100) y un carácter especial para decorarlo.
4+
5+
La función debe devolver un string que represente el árbol de Navidad, construido de la siguiente manera:
6+
7+
- El árbol está compuesto de triángulos de caracteres especiales.
8+
- Los espacios en blanco a los lados del árbol se representan con guiones bajos _.
9+
- Todos los árboles tienen un tronco de dos líneas, representado por el carácter #.
10+
- El árbol siempre debe tener la misma longitud por cada lado.
11+
- Debes asegurarte de que el árbol tenga la forma correcta usando saltos de línea \n para cada línea.
12+
13+
**Ejemplos:**
14+
15+
```js
16+
const tree = createXmasTree(5, '*')
17+
console.log(tree)
18+
/*
19+
____*____
20+
___***___
21+
__*****__
22+
_*******_
23+
*********
24+
____#____
25+
____#____
26+
*/
27+
28+
const tree2 = createXmasTree(3, '+')
29+
console.log(tree2)
30+
/*
31+
__+__
32+
_+++_
33+
+++++
34+
__#__
35+
__#__
36+
*/
37+
38+
const tree3 = createXmasTree(6, '@')
39+
console.log(tree3)
40+
/*
41+
_____@_____
42+
____@@@____
43+
___@@@@@___
44+
__@@@@@@@__
45+
_@@@@@@@@@_
46+
@@@@@@@@@@@
47+
_____#_____
48+
_____#_____
49+
*/
50+
```
51+
52+
Asegúrate de utilizar saltos de línea \n al final de cada línea, excepto en la última.
53+
54+
## Mi solución explicada
55+
56+
```js
57+
function createXmasTree(height, ornament) {
58+
const totalWidth = 2 * height - 1;
59+
const trunkPadding = '_'.repeat((totalWidth - 1) / 2);
60+
61+
const tree = Array.from({ length: height }, (_, i) => {
62+
const layerWidth = 2 * i + 1;
63+
const spaces = '_'.repeat((totalWidth - layerWidth) / 2);
64+
return spaces + ornament.repeat(layerWidth) + spaces;
65+
});
66+
67+
const trunk = `${trunkPadding}#${trunkPadding}`;
68+
tree.push(trunk, trunk);
69+
70+
return tree.join('\n');
71+
}
72+
```
73+
74+
Primero, calculamos el ancho total del árbol. Multiplicamos la altura por 2 y le restamos 1 para obtener el ancho total.
75+
76+
```js
77+
const totalWidth = 2 * height - 1;
78+
```
79+
80+
¿Por qué la fórmula `(2 * height - 1)`?
81+
82+
Tomemos como ejemplo un árbol de altura 5. (`createXmasTree(5, '*')`) El ancho total del árbol es 9. Si multiplicamos la altura por 2, obtenemos 10, pero el ancho real del árbol es 9. Por eso restamos 1.
83+
84+
Luego, calculamos el relleno del tronco del árbol. El relleno del tronco es igual a la mitad del ancho total (anteriormente calcualado) menos 1 (para que el tronco tenga la misma longitud por cada lado). Usamos el método `repeat` para crear una cadena de guiones bajos del tamaño adecuado.
85+
86+
```js
87+
const trunkPadding = '_'.repeat((totalWidth - 1) / 2);
88+
```
89+
90+
Después, creamos el árbol. Usamos `Array.from` para crear un array de longitud `height`. Iteramos sobre cada elemento del array y calculamos el ancho de la capa actual. El ancho de la capa actual es igual a `2 * i + 1`, donde `i` es el índice actual.
91+
92+
```js
93+
const tree = Array.from({ length: height }, (_, i) => {
94+
const layerWidth = 2 * i + 1;
95+
const spaces = '_'.repeat((totalWidth - layerWidth) / 2);
96+
return spaces + ornament.repeat(layerWidth) + spaces;
97+
});
98+
```
99+
100+
Para cada capa, calculamos la cantidad de espacios a cada lado de la capa. La cantidad de espacios es igual a `(totalWidth - layerWidth) / 2`.
101+
102+
Por ejemplo, para la primera capa de un árbol de altura 5, el ancho de la capa es 1. El ancho total del árbol es 9. Por lo tanto, la cantidad de espacios a cada lado de la capa es `(9 - 1) / 2 = 4`. Para el adorno, repetimos el carácter especial de la capa `layerWidth` veces. Una vez que tenemos los espacios y el adorno, los concatenamos para formar la capa -> `spaces + ornament.repeat(layerWidth) + spaces`.
103+
104+
Quedando asi:
105+
106+
```txt
107+
(9 - 1) / 2 = 4 --> 4 espacios a cada lado
108+
2 * 0 + 1 = 1 --> 1 adorno (ornament)
109+
110+
____*____
111+
112+
```
113+
114+
Para la segunda capa, el ancho de la capa es 3. La cantidad de espacios a cada lado de la capa es `(9 - 3) / 2 = 3`.
115+
116+
```txt
117+
(9 - 3) / 2 = 3 --> 3 espacios a cada lado
118+
2 * 1 + 1 = 3 --> 3 adornos (ornament)
119+
120+
___***___
121+
122+
```
123+
124+
Para la tercera capa, el ancho de la capa es 5. La cantidad de espacios a cada lado de la capa es `(9 - 5) / 2 = 2`.
125+
126+
```txt
127+
(9 - 5) / 2 = 2 --> 2 espacios a cada lado
128+
2 * 2 + 1 = 5 --> 5 adornos (ornament)
129+
130+
__*****__
131+
132+
```
133+
134+
Para la cuarta capa, el ancho de la capa es 7. La cantidad de espacios a cada lado de la capa es `(9 - 7) / 2 = 1`.
135+
136+
```txt
137+
(9 - 7) / 2 = 1 --> 1 espacio a cada lado
138+
2 * 3 + 1 = 7 --> 7 adornos (ornament)
139+
140+
_*******_
141+
142+
```
143+
144+
Para la quinta capa, el ancho de la capa es 9. La cantidad de espacios a cada lado de la capa es `(9 - 9) / 2 = 0`.
145+
146+
```txt
147+
(9 - 9) / 2 = 0 --> 0 espacios a cada lado
148+
2 * 4 + 1 = 9 --> 9 adornos (ornament)
149+
150+
*********
151+
152+
```
153+
154+
Dando como resultado:
155+
156+
```txt
157+
____*____
158+
___***___
159+
__*****__
160+
_*******_
161+
*********
162+
```
163+
164+
Finalmente, creamos el tronco del árbol. El tronco del árbol es simplemente una cadena de guiones bajos seguida de dos almohadillas y otra cadena de guiones bajos.
165+
166+
```js
167+
const trunk = `${trunkPadding}#${trunkPadding}`;
168+
tree.push(trunk, trunk);
169+
```
170+
171+
Nuevo árbol:
172+
173+
```txt
174+
____*____
175+
___***___
176+
__*****__
177+
_*******_
178+
*********
179+
____#____
180+
____#____
181+
```
182+
183+
Unimos todas las capas del árbol con saltos de línea y devolvemos el árbol completo.
184+
185+
```js
186+
return tree.join('\n');
187+
```
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function createXmasTree(height, ornament) {
2+
const totalWidth = 2 * height - 1;
3+
const trunkPadding = '_'.repeat((totalWidth - 1) / 2);
4+
5+
const tree = Array.from({ length: height }, (_, i) => {
6+
const layerWidth = 2 * i + 1;
7+
const spaces = '_'.repeat((totalWidth - layerWidth) / 2);
8+
return spaces + ornament.repeat(layerWidth) + spaces;
9+
});
10+
11+
const trunk = `${trunkPadding}#${trunkPadding}`;
12+
tree.push(trunk, trunk);
13+
14+
return tree.join('\n');
15+
}
16+
17+
module.exports = createXmasTree;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const createXmasTree = require('./index');
2+
3+
describe('04 => Decorando-el-arbol-de-navidad', () => {
4+
const TEST_CASES = [
5+
{
6+
input: [3, '*'],
7+
output: '__*__\n_***_\n*****\n__#__\n__#__',
8+
},
9+
{
10+
input: [5, '+'],
11+
output:
12+
'____+____\n___+++___\n__+++++__\n_+++++++_\n+++++++++\n____#____\n____#____',
13+
},
14+
{
15+
input: [6, '@'],
16+
output:
17+
'_____@_____\n____@@@____\n___@@@@@___\n__@@@@@@@__\n_@@@@@@@@@_\n@@@@@@@@@@@\n_____#_____\n_____#_____',
18+
},
19+
{
20+
input: [1, '*'],
21+
output: '*\n#\n#',
22+
},
23+
{
24+
input: [4, '#'],
25+
output: '___#___\n__###__\n_#####_\n#######\n___#___\n___#___',
26+
},
27+
];
28+
29+
it('should return a string', () => {
30+
expect(typeof createXmasTree(3, '*')).toBe('string');
31+
});
32+
33+
it.each(TEST_CASES)(
34+
'should return the expected output',
35+
({ input, output }) => {
36+
expect(createXmasTree(...input)).toBe(output);
37+
},
38+
);
39+
});

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ npm run test 'year'/'challenge'/index.test.js
6262
| 01 | [🎁 ¡Primer regalo repetido!](https://adventjs.dev/es/challenges/2024/1) | 🟢 | [here](./2024/01-primer-regalo-repetido/index.js) | ⭐⭐⭐⭐⭐ |
6363
| 02 | [🖼️ Enmarcando nombres](https://adventjs.dev/es/challenges/2024/2) | 🟢 | [here](./2024/02-enmarcando-nombres/index.js) | ⭐⭐⭐⭐⭐ |
6464
| 03 | [🏗️ Organizando el inventario](https://adventjs.dev/es/challenges/2024/3) | 🟢 | [here](./2024/03-organizando-el-inventario/index.js) | ⭐⭐⭐⭐⭐ |
65+
| 04 | [🎄 Decorando el árbol de Navidad](https://adventjs.dev/es/challenges/2024/4) | 🟡 | [here](./2024/04-decorando-el-arbol-de-navidad/index.js) | ⭐⭐⭐⭐⭐ |
6566

6667
Difficulties legend:
6768
🟢 Easy 🟡 Medium 🔴 Hard

0 commit comments

Comments
 (0)