Skip to content

Commit e4bf133

Browse files
authored
Merge pull request #8 from marcode24/2023
✨ add challenge-07 solution
2 parents 4a782cd + 19a0135 commit e4bf133

File tree

3 files changed

+201
-0
lines changed

3 files changed

+201
-0
lines changed

2023/07-las-cajas-en-3d/README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# Reto 07: Las cajas en 3d
2+
3+
## Problema
4+
5+
Santa está experimentando con nuevos diseños de regalos y **necesita tu ayuda para visualizarlos en 3D.**
6+
7+
Tu tarea es escribir una función que, dado un tamaño n (entero), **genere un dibujo de un regalo en 3D** utilizando caracteres ASCII.
8+
9+
Las líneas de los regalos se dibujan con # y las caras con el símbolo que nos pasan como parámetro:
10+
11+
```js
12+
drawGift(4, '+')
13+
14+
/*
15+
####
16+
#++##
17+
#++#+#
18+
####++#
19+
#++#+#
20+
#++##
21+
####
22+
*/
23+
24+
drawGift(5, '*')
25+
/*
26+
#####
27+
#***##
28+
#***#*#
29+
#***#**#
30+
#####***#
31+
#***#**#
32+
#***#*#
33+
#***##
34+
#####
35+
*/
36+
37+
drawGift(1, '^')
38+
/*
39+
#
40+
*/
41+
```
42+
43+
Importante: Nos han dicho que **siempre hay que dejar un salto de línea al final del dibujo.**
44+
45+
**Nota:** Ten en cuenta que, en los tests, la primera línea se ve empujada por el caracter `"`.
46+
47+
## Mi solución
48+
49+
```js
50+
const drawGift = (size, symbol) => {
51+
const WRAPPER = '#';
52+
const SPACE = ' ';
53+
54+
if (size <= 1) return `${WRAPPER}\n`;
55+
56+
const top = [SPACE.repeat(size - 1) + WRAPPER.repeat(size)];
57+
const bottom = [`${WRAPPER.repeat(size)}`];
58+
const middle = `${WRAPPER.repeat(size)}${symbol.repeat(Math.abs(size - 2))}`
59+
+ `${WRAPPER}\n`;
60+
for (let i = 1; i < size; i++) {
61+
const line = `${WRAPPER}${symbol.repeat(size - 2)}${WRAPPER}`
62+
+ `${symbol.repeat(i - 1)}${WRAPPER}`;
63+
top.push(SPACE.repeat(size - i - 1) + line);
64+
bottom.push(line);
65+
}
66+
67+
top.pop();
68+
bottom.pop();
69+
top.push(middle);
70+
bottom.reverse();
71+
return `${top.join('\n')}${bottom.join('\n')}\n`;
72+
};
73+
```
74+
75+
## Expliación de mi solución
76+
77+
En primer lugar, defino las constantes `WRAPPER` y `SPACE` para poder cambiarlas fácilmente en caso de que se necesite.
78+
79+
```js
80+
const WRAPPER = '#';
81+
const SPACE = ' ';
82+
```
83+
84+
A continuación, compruebo si el tamaño es menor o igual a 1, en cuyo caso devuelvo el dibujo del regalo más pequeño posible.
85+
86+
```js
87+
if (size <= 1) return `${WRAPPER}\n`;
88+
```
89+
90+
Después, creo los arrays `top` y `bottom` que contendrán las líneas superiores e inferiores del regalo respectivamente. En el caso de `top`, la primera línea es la que contiene el lazo superior del regalo, por lo que la añado directamente al array. En el caso de `bottom`, la primera línea es la que contiene el lazo inferior del regalo, por lo que la añado al array al revés.
91+
92+
```js
93+
const top = [SPACE.repeat(size - 1) + WRAPPER.repeat(size)];
94+
const bottom = [`${WRAPPER.repeat(size)}`];
95+
```
96+
97+
A continuación, creo la línea del medio del regalo, que es la que contiene el lazo central. Para ello, concateno el símbolo que se pasa como parámetro al tamaño del regalo menos 2, que es el número de caracteres que hay entre los dos lazos, y a continuación concateno el lazo central. Por último, añado un salto de línea.
98+
99+
```js
100+
const middle = `${WRAPPER.repeat(size)}${symbol.repeat(Math.abs(size - 2))}`
101+
+ `${WRAPPER}\n`;
102+
```
103+
104+
A continuación, creo un bucle que itera desde 1 hasta el tamaño del regalo. En cada iteración, creo la línea correspondiente al lazo superior del regalo. Para ello, concateno el lazo superior, el símbolo que se pasa como parámetro repetido tantas veces como el tamaño del regalo menos 2, que es el número de caracteres que hay entre los dos lazos, y el lazo superior repetido tantas veces como el número de la iteración menos 1. Por último, añado la línea al array `top`.
105+
106+
```js
107+
for (let i = 1; i < size; i++) {
108+
const line = `${WRAPPER}${symbol.repeat(size - 2)}${WRAPPER}`
109+
+ `${symbol.repeat(i - 1)}${WRAPPER}`;
110+
top.push(SPACE.repeat(size - i - 1) + line);
111+
}
112+
```
113+
114+
A continuación, elimino la última línea del array `top` y la añado al array `bottom`.
115+
116+
```js
117+
top.pop();
118+
bottom.push(line);
119+
```
120+
121+
A continuación, añado la línea del medio del regalo al array `top`.
122+
123+
```js
124+
top.push(middle);
125+
```
126+
127+
A continuación, invierto el orden de los elementos del array `bottom` y los añado al array `top`.
128+
129+
```js
130+
bottom.reverse();
131+
top.push(...bottom);
132+
```
133+
134+
Por último, devuelvo el array `top` convertido en un string, añadiendo un salto de línea al final.
135+
136+
```js
137+
return `${top.join('\n')}\n`;
138+
```

2023/07-las-cajas-en-3d/index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const drawGift = (size, symbol) => {
2+
const WRAPPER = '#';
3+
const SPACE = ' ';
4+
5+
if (size <= 1) return `${WRAPPER}\n`;
6+
7+
const top = [SPACE.repeat(size - 1) + WRAPPER.repeat(size)];
8+
const bottom = [`${WRAPPER.repeat(size)}`];
9+
const middle = `${WRAPPER.repeat(size)}${symbol.repeat(Math.abs(size - 2))}`
10+
+ `${WRAPPER}\n`;
11+
for (let i = 1; i < size; i++) {
12+
const line = `${WRAPPER}${symbol.repeat(size - 2)}${WRAPPER}`
13+
+ `${symbol.repeat(i - 1)}${WRAPPER}`;
14+
top.push(SPACE.repeat(size - i - 1) + line);
15+
bottom.push(line);
16+
}
17+
18+
top.pop();
19+
bottom.pop();
20+
top.push(middle);
21+
bottom.reverse();
22+
return `${top.join('\n')}${bottom.join('\n')}\n`;
23+
};
24+
25+
module.exports = drawGift;

2023/07-las-cajas-en-3d/index.test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const drawGift = require('./index');
2+
3+
describe('07 => Las cajas en 3d', () => {
4+
const testCases = [
5+
{
6+
input: [4, '+'],
7+
output: ' ####\n #++##\n #++#+#\n####++#\n#++#+#\n#++##\n####\n',
8+
},
9+
{
10+
input: [1, '^'],
11+
output: '#\n',
12+
},
13+
{
14+
input: [5, '*'],
15+
output: ' #####\n #***##\n #***#*#\n #***#**#\n#####***#\n#***#**#\n#***#*#\n#***##\n#####\n',
16+
},
17+
{
18+
input: [2, '&'],
19+
output: ' ##\n###\n##\n',
20+
},
21+
{
22+
input: [10, '%'],
23+
output: ' ##########\n #%%%%%%%%##\n #%%%%%%%%#%#\n #%%%%%%%%#%%#'
24+
+ '\n #%%%%%%%%#%%%#\n #%%%%%%%%#%%%%#\n #%%%%%%%%#%%%%%#\n #%%%%%%%%#%%%%%%#'
25+
+ '\n #%%%%%%%%#%%%%%%%#\n##########%%%%%%%%#\n#%%%%%%%%#%%%%%%%#\n#%%%%%%%%#%%%%%%#'
26+
+ '\n#%%%%%%%%#%%%%%#\n#%%%%%%%%#%%%%#\n#%%%%%%%%#%%%#\n#%%%%%%%%#%%#\n#%%%%%%%%#%#'
27+
+ '\n#%%%%%%%%##\n##########\n',
28+
},
29+
];
30+
31+
it('should return a string type', () => {
32+
expect(typeof drawGift(1, '*')).toBe('string');
33+
});
34+
35+
it.each(testCases)('should return the correct output', ({ input, output }) => {
36+
expect(drawGift(...input)).toBe(output);
37+
});
38+
});

0 commit comments

Comments
 (0)