|
| 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 | +``` |
0 commit comments