DEV Community

Cover image for AdventJS 2023: Reto del Día 8
Fenriuz
Fenriuz

Posted on

AdventJS 2023: Reto del Día 8

Solución al reto #8 del AdventJS 2023

Solución del reto anterior

Solución del siguiente reto

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 de a 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)
*/
Enter fullscreen mode Exit fullscreen mode

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

  1. 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;
}
Enter fullscreen mode Exit fullscreen mode

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('');
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)