Solución al reto #7 del AdventJS 2023
Solución del reto anterior
Solución del siguiente reto
Descripción del Reto
Santa está experimentando con nuevos diseños de regalos y necesita tu ayuda para visualizarlos en 3D.
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.
Las líneas de los regalos se dibujan con # y las caras con el símbolo que nos pasan como parámetro:
drawGift(4, '+')
/*
####
#++##
#++#+#
####++#
#++#+#
#++##
####
*/
drawGift(5, '*')
/*
#####
#***##
#***#*#
#***#**#
#####***#
#***#**#
#***#*#
#***##
#####
*/
drawGift(1, '^')
/*
#
*/
Importante: Nos han dicho que siempre hay que dejar un salto de línea al final del dibujo.
Nota: Ten en cuenta que, en los tests, la primera línea se ve empujada por el caracter ".
Análisis
En este reto básicamente hay que dibujar los regalos en base a los parámetros que nos da el ejercicio, al puro estilo del ASCII Art. Por si no has terminado de entenderlo, aquí un ejemplo:
#####
#***##
#***#*#
#***#**#
#####***#
#***#**#
#***#*#
#***##
#####
Lo de arriba es básicamente un rectangulo en 3D
Donde los #
representan el contorno del rectángulo, es decir las líneas, mientras que el símbolo que nos pasen como parámetro (en este caso *
) representa la cara o la superficie del rectángulo.
Entradas
- Size(
size
): Un número que representa el tamaño del regalo, es la longitud en caracteres de cada línea del regalo. - Symbol(
symbol
): Un string que será lo que rellene el regalo, básicamente llena cada cara del rectángulo.
Salida
- Un string que se verá como el dibujo del regalo solocitado en las entradas. ### Consideraciones
- Siempre hay que dejar un salto de línea al final del dibujo.
- Hay que tomar en cuenta los espacios en la primera mitad del dibujo, son importantes para darle forma al regalo.
Solución
El ejercicio en sí no tiene mucha complejidad, lo complicado en realidad puede ser manejar el string para dibujar, pero JavaScript ofrece suficientes métodos para ello.
Código
/**
* Genera un regalo hecho de símbolos en forma de rectángulo.
*
* @param {number} size - El tamaño del regalo, determina el ancho y la altura del rectángulo.
* @param {string} symbol - El símbolo utilizado para dibujar el regalo.
* @return {string} - La representación del regalo como una cadena.
*/
function drawGift(size, symbol) {
// El espacio al principio del regalo
let space = size;
// Inicializa la primera parte del regalo
// el espacio al principio del regalo
// y concatena # con el tamaño del regalo
let firstPart = " ".repeat(--space) + "#".repeat(size) + "\n";
// si el tamaño es 1, devuelve la primera parte `#`
if (size === 1) {
return firstPart;
}
// Inicializa la segunda parte del regalo
// esta parte es después de la mitad del regalo
let secondPart = "";
// bucle a través del tamaño del regalo -2
// -2 porque ya tenemos la primera y la última línea
for (let i = 0; i < size - 2; i += 1) {
// comienza con el espacio al principio del regalo
const initialSpace = " ".repeat(--space);
// añade `#` y el símbolo con el tamaño del regalo - 1
const upperFace = "#".padEnd(size - 1, symbol);
// añade `#` y llena el espacio con el símbolo
const rightFace = "#".padEnd(i + 1, symbol)
// concatena todos ellos y añade el salto de línea
firstPart += initialSpace + upperFace + rightFace + "#\n";
// añade los símbolos en la cara frontal
const frontFace = symbol.repeat(size - 2);
// añade los símbolos en la cara inferior derecha
const lowerRightFace = "#".padEnd(size - i - 2, symbol);
// concatena todos ellos
secondPart += "#" + frontFace + lowerRightFace + "#\n";
}
// la mitad es `#` con el tamaño del regalo y el símbolo con el tamaño del regalo - 2
const half = "#".repeat(size) + symbol.repeat(size - 2) + "#\n";
// devuelve la primera parte, la mitad y la segunda parte
return firstPart + half + secondPart + "#".repeat(size) + "\n";
}
Soluciones de la comunidad
Solución por marcode24:
const drawGift = (size, symbol) => {
const WRAPPER = '#';
const SPACE = ' ';
if (size <= 1) return `${WRAPPER}\n`;
const top = [SPACE.repeat(size - 1) + WRAPPER.repeat(size)];
const bottom = [`${WRAPPER.repeat(size)}`];
const middle = `${WRAPPER.repeat(size)}${symbol.repeat(Math.abs(size - 2))}`
+ `${WRAPPER}\n`;
for (let i = 1; i < size; i++) {
const line = `${WRAPPER}${symbol.repeat(size - 2)}${WRAPPER}`
+ `${symbol.repeat(i - 1)}${WRAPPER}`;
top.push(SPACE.repeat(size - i - 1) + line);
bottom.push(line);
}
top.pop();
bottom.pop();
top.push(middle);
bottom.reverse();
return `${top.join('\n')}${bottom.join('\n')}\n`;
};
Solución por Achalogy:
function drawGift(size, symbol) {
let bgSize = size - 2
bgSize += +!(bgSize + 1)
let response = ""
let topCenter = ""
let bottomCenter = ""
for (const a of [...Array.from({ length: bgSize }).keys()]) {
const c = "#"
+ symbol.repeat(bgSize)
+ "#" + symbol.repeat(a) + "#"
bottomCenter = c + "\n" + bottomCenter
topCenter += " ".repeat(bgSize - a) + c + "\n"
}
response = " ".repeat(size - 1) + "#".repeat(size) + "\n"
+ (topCenter
+ "#".repeat(size) + symbol.repeat(bgSize) + "#" + "\n"
+ bottomCenter
+ "#".repeat(size) + "\n").repeat(+!!(size - 1))
return response
}
Y ese fue el reto para el 7 de diciembre y sus soluciones. ¿Tienes otra solución alternativa? ¡Déjala en los comentarios!
Top comments (0)