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)