Skip to content

Commit 6afbb77

Browse files
committed
Explicación y simplificación Reto 7
1 parent 86511ec commit 6afbb77

File tree

2 files changed

+183
-5
lines changed

2 files changed

+183
-5
lines changed

retos/reto-7/README.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Reto 7
2+
3+
Santa está experimentando con nuevos diseños de regalos y **necesita tu ayuda para visualizarlos en 3D**.
4+
5+
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.
6+
7+
Las líneas de los regalos se dibujan con `#` y las caras con el símbolo que nos pasan como parámetro:
8+
9+
```js
10+
drawGift(4, "+");
11+
12+
/*
13+
####
14+
#++##
15+
#++#+#
16+
####++#
17+
#++#+#
18+
#++##
19+
####
20+
*/
21+
22+
drawGift(5, "*");
23+
/*
24+
#####
25+
#***##
26+
#***#*#
27+
#***#**#
28+
#####***#
29+
#***#**#
30+
#***#*#
31+
#***##
32+
#####
33+
*/
34+
35+
drawGift(1, "^");
36+
/*
37+
#
38+
*/
39+
```
40+
41+
Importante: Nos han dicho que **siempre hay que dejar un salto de línea al final del dibujo**.
42+
43+
**Nota**: Ten en cuenta que, en los tests, la primera línea se ve empujada por el caracter ".
44+
45+
# Solución
46+
47+
Primero debemos definir los números que vamos a usar, es decir, qué tamaño tendrá el regalo y que tamaño tendrá el fondo o la cara de cada regalo, por ejemplo, en un regalo de tamaño 4, el fondo (`+`) es de tamaño 2 y los bordes son del mismo tamaño que el regalo:
48+
49+
```
50+
#### // Tamaño 4 = Tamaño del regalo
51+
#++##
52+
#++#+#
53+
####++#
54+
#++#+#
55+
#++##
56+
#### // Tamaño 4 = Tamaño del regalo
57+
```
58+
59+
Debemos tener cuidado con los negativos, ya que si tenemos un cuadrado de tamaño 1, el tamaño del fondo será de -1, para esto podemos usar un condicional cuando lo necesitemos, pero una versión que no aumente la complejidad es agregarle el símbolo contrario de `bgSize + 1`, ya que:
60+
61+
```js
62+
size = 3;
63+
bgSize = size - 2; // 1
64+
65+
bgSize += +!(bgSize + 1);
66+
// +!(2)
67+
// +false
68+
// 0
69+
```
70+
71+
```js
72+
size = 2;
73+
bgSize = size - 2; // 0
74+
75+
bgSize += +!(bgSize + 1);
76+
// +!(1)
77+
// +false
78+
// 0
79+
```
80+
81+
```js
82+
size = 1;
83+
bgSize = size - 2; // -1
84+
85+
bgSize += +!(bgSize + 1);
86+
// +!(0)
87+
// +true
88+
// 1
89+
```
90+
91+
Esta solución tiene en cuenta que nunca se pedirá un regalo de tamaño 0.
92+
93+
Ya con estos valores podemos crear la parte de arriba, la parte de abajo y el centro.
94+
95+
```js
96+
const top = " ".repeat(size - 1) + "#".repeat(size) + "\n";
97+
const center = "#".repeat(size) + symbol.repeat(bgSize) + "#" + "\n";
98+
const bottom = "#".repeat(size) + "\n";
99+
```
100+
101+
Ahora solo debemos calcular lo que va entre estas 3 lineas:
102+
103+
```
104+
--------- TOP
105+
#++##
106+
#++#+#
107+
--------- CENTER
108+
#++#+#
109+
#++##
110+
--------- BOTTOM
111+
```
112+
113+
Si nos fijamos, podemos ver que ambas partes son iguales, solo que están del revés y una no tiene espacios al inicio, así que primero calcularemos la parte de abajo, con un ciclo que vaya desde `0` hasta `bgSize-1` la definiremos como:
114+
115+
```js
116+
const c = "#" + symbol.repeat(bgSize) + "#" + symbol.repeat(a) + "#";
117+
```
118+
119+
Que nos dará algo como esto, que deberemos reversar para la parte centro-abajo:
120+
121+
```
122+
IT1 - #++##
123+
IT2 - #++#+#
124+
```
125+
126+
La siguiente linea reversa y guarda el centro-abajo en una variable:
127+
128+
```js
129+
bottomCenter = c + "\n" + bottomCenter;
130+
```
131+
132+
Y para la parte de arriba, calcularemos los espacios que van antes con:
133+
134+
```js
135+
topCenter += " ".repeat(bgSize - a) + c + "\n";
136+
```
137+
138+
Ya con esto, podemos definir nuestra respuesta como la suma de cada una de las partes, menos en el caso en que `size = 1`, acá es cuando tendremos que validar si `size > 0`.
139+
140+
## Optimización
141+
142+
Si revisaste mi solución, verás algunas cosas raras, estas son importantes para lograr el puntaje más alto, ya que se encargan de reducir la complejidad.
143+
144+
### Ciclo con Complejidad 0
145+
146+
Al parecer, hacer uso de `for .. of` no aumenta la complejidad, este itera un arreglo, así que primero tendremos que hacer un arreglo lleno con los números desde `0` hasta `bgSize-1`, la forma de hacerlo sin aumentar la complejidad es:
147+
148+
```js
149+
[...Array.from({ length: bgSize }).keys()]
150+
```
151+
152+
### Usar `.repeat()` para evitar el último condicional
153+
154+
Podemos usar repeat con el valor numerico del signo de `size-1`, ya que el caso en el que necesitamos que no se agreguen todas las partes a la respuesta es cuando `size = 1`, así que si repetimos `+!!(size -1)` veces el texto, en el caso de `size = 1` se repetirá 0 veces.
155+
156+
```js
157+
const size = 3
158+
// +!!(size - 1)
159+
// +!!(2)
160+
// +true
161+
// 1
162+
```
163+
164+
```js
165+
const size = 2
166+
// +!!(size - 1)
167+
// +!!(1)
168+
// +true
169+
// 1
170+
```
171+
172+
```js
173+
const size = 1
174+
// +!!(size - 1)
175+
// +!!(0)
176+
// +false
177+
// 0
178+
```

retos/reto-7/main.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ function drawGift(size, symbol) {
55

66
let response = ""
77

8-
let center = ""
8+
let topCenter = ""
99
let bottomCenter = ""
1010

11-
for (const a of [...Array.from({ length: size - 2 }).keys()]) {
11+
for (const a of [...Array.from({ length: bgSize }).keys()]) {
1212
const c = "#"
1313
+ symbol.repeat(bgSize)
1414
+ "#" + symbol.repeat(a) + "#"
15-
center += " ".repeat(size - a - 2) + c + "\n"
1615
bottomCenter = c + "\n" + bottomCenter
16+
topCenter += " ".repeat(bgSize - a) + c + "\n"
1717
}
1818

19-
response = (" ".repeat(size) + "#".repeat(size) + "\n").slice(1)
20-
+ (center
19+
response = " ".repeat(size - 1) + "#".repeat(size) + "\n"
20+
+ (topCenter
2121
+ "#".repeat(size) + symbol.repeat(bgSize) + "#" + "\n"
2222
+ bottomCenter
2323
+ "#".repeat(size) + "\n").repeat(+!!(size - 1))

0 commit comments

Comments
 (0)