Solución al reto #8 del AdventJS 2023
Descripción del Reto
Los elfos están muy ocupados en el taller de Santa Claus organizando regalos 🎁 para la víspera de Navidad 🎄.
El formato de entrada es especial, ya que indica el número de regalos y el tipo de regalo con letras de la a
a la z
. Por ejemplo, '66a11b'
significa 66 regalos a
y 11 regalos b
.
Los elfos tienen un sistema especial para organizar los regalos:
- Cada 10 regalos del mismo tipo se empaquetan en una caja, representada por
{x}
. Por ejemplo, 20 regalos tipo a se empaquetan en 2 cajas así:{a}{a}
. - Cada 5 cajas se apilan en un palé, representado por
[x]
. Por ejemplo, 10 cajas dea
se apilan en 2 palés de esta manera:[a][a]
- Cualquier regalo adicional se coloca en una bolsa, representada por
()
y se colocan todas dentro. Por ejemplo 4 regalos de b se colocan en una bolsa así(bbbb)
Los regalos luego se colocan en el siguiente orden: palés, cajas y bolsas. Y los regalos aparecen en el mismo orden que la cadena de entrada.
Tu tarea es escribir una función organizeGifts
que tome una cadena de regalos como argumento y devuelva una cadena representando el almacén.
const result1 = organizeGifts(`76a11b`) console.log(result1) // '[a]{a}{a}(aaaaaa){b}(b)' /* Explicación: 76a: 76 regalos tipo 'a' se empaquetarían en 7 cajas y sobrarían 6 regalos, resultando en 1 palé [a] (por las primeras 5 cajas), 2 cajas sueltas {a}{a} y una bolsa con 6 regalos (aaaaaa) 11b: 11 regalos tipo 'b' se empaquetarían en 1 caja y sobraría 1 regalo, resultando en 1 caja suelta {b} y una bolsa con 1 regalo (b) */
Análisis
El objetivo es desglozar el string en partes, para dividir las cantidades de cada regalo, una vez hecho eso se pueden empaquetar como lo marcaron los requerimientos.
Entrada
- Gifts(
gifts
): Un string con la cantidad de cada tipo de regalo.
Salida
- Un string con los regalos empaquetados.
Consideraciones
- El valor de retorno debe ir en el mismo orden de la entrada, o sea, siguiendo el orden de los regalos.
Solución
Podemos tomar el string de entrada y dividirlo entre la cantidad de regalos de cada tipo, usando RegExp. Una vez hecho eso iteramos entre cada uno de ellos y procedemos a dividir para encontral cantidad de palés, cajas y bolsas.
Código
/** * Organiza una lista de regalos. * * @param {string} gifts - La lista de regalos a organizar. * @returns {string} - La representación organizada de los regalos. */ function organizeGifts(gifts) { let res = ""; // Busca secuencias de una o más cifras numéricas seguidas de una letra minúscula const giftsSplit = gifts.match(/\d+[a-z]/g); // Iterar sobre cada regalo en el array giftsSplit for (const gift of giftsSplit) { const quantity = Number(gift.slice(0, -1)); const giftType = gift.charAt(gift.length - 1); // Calcular el número de palés necesarios const pallets = `[${giftType}]`.repeat(Math.floor(quantity / 50)); // Calcular el resto después de empaquetar en palés const remainder = quantity % 50; // Calcular el número de cajas necesarias const boxes = `{${giftType}}`.repeat(Math.floor(remainder / 10)); // Calcular los regalos restantes después de empaquetar en cajas const remainderGifts = giftType.repeat(remainder % 10); // Verificar si hay regalos restantes y crear una bolsa const bags = remainderGifts && `(${remainderGifts})`; // Concatenar los palés, cajas y bolsas para el regalo actual res += pallets + boxes + bags; } // Devolver la representación organizada de los regalos return res; }
Soluciones de la comunidad
Solución por cristianstu:
function organizeGifts(gifts) { const matches = [...gifts.matchAll(/(\d+)([a-z])/g)]; return matches.map(([,qtty, letter]) => { qtty = +qtty const pales = Math.trunc(qtty / 50) const boxes = Math.trunc((qtty - (50 * pales)) / 10) const bags = qtty - (pales * 50) - (boxes * 10) return `[${letter}]`.repeat(pales) + `{${letter}}`.repeat(boxes) + `(${letter})`.repeat(bags).replace(/\)\(/g, '') }).join(''); }
Solución por jamerrq:
function organizeGifts (gifts: string): string { const giftsRegex = /(\d+)([a-z])/g const giftsMatches = gifts.matchAll(giftsRegex) let ans = '' for (const match of giftsMatches) { const [, qty, symbol] = match let left = +qty ans = `${ans}${`[${symbol}]`.repeat((left - (left % 50)) / 50)}` left -= 50 * ((left - (left % 50)) / 50) ans = `${ans}${`{${symbol}}`.repeat((left - (left % 10)) / 10)}` left -= 10 * (left - (left % 10)) / 10 const x = ((left - 1) + ((left - 1) >> 31)) ^ ((left - 1) >> 31) ans = `${ans}${`(${symbol.repeat(left)})`.repeat((left + 1 - x) / 2)}` } return ans }
Y ese fue el reto para el 8 de diciembre y sus soluciones. Dale like si te ha gustado el reto o la solución!
¿Tienes otra solución alternativa? ¡Déjala en los comentarios!
Top comments (0)