DEV Community

Cover image for AdventJS 2023: Day 8 Challenge
Fenriuz
Fenriuz

Posted on • Originally published at alexvalle.dev on

AdventJS 2023: Day 8 Challenge

The solution to the Challenge #8 of AdventJS 2023

The solution to the previous challenge

The solution to the next challenge

Challenge Description

The elves are very busy in Santa Claus' workshop organizing gifts 🎁 for Christmas Eve 🎄.

The input format is special, as it indicates the number of gifts and the type of gift with letters from a to z. For example, '66a11b' means 66 a gifts and 11 b gifts.

The elves have a special system for organizing the gifts:

  • Every 10 gifts of the same type are packed in a box, represented by {x}. For example, 20 type a gifts are packed in two boxes like this: {a}{a}.

  • Every 5 boxes are stacked on a pallet, represented by [x]. For example, 10 a boxes are stacked on 2 pallets in this way: [a][a]

  • Any additional gift is placed in a bag, represented by () and all of them are placed inside. For example, 4 b gifts are placed in a bag like this (bbbb)

The gifts are then placed in the following order : pallets, boxes and bags. The gifts appear in the same order as the input string.

Your task is to write a function organizeGifts takes a string of gifts as an argument and returns a string representing the warehouse.

const result1 = organizeGifts('76a11b')
console.log(result1)
// `[a]{a}{a}(aaaaaa){b}(b)`

/* Explanation:

  76a: 76 gifts type 'a' would be packed in 7 boxes and 6 gifts would be left, resulting in 1 pallet [a] (for the first 5 boxes), 2 loose boxes {a}{a} and a bag with 6 gifts (aaaaaa)

  11b: 11 gifts type 'b' would be packed in 1 box and 1 gift would be left, resulting in 1 loose box {b} and a bag with 1 gift (b)
*/

Enter fullscreen mode Exit fullscreen mode

Analysis

The goal is to break down the string into parts, to divide the quantities of each gift, and once that is done, they can be packaged as marked by the requirements.

Input

  1. Gifts (gifts): A string with the quantity of each type of gift.

Output

  • A string with the packaged gifts.

Considerations

  • The return value should be in the same order as the input, following the order of the gifts.

Solution

We can take the input string and split it between the number of gifts of each type, using RegExp. Once that is done, we iterate through each of them and proceed to divide to find the number of pallets, boxes, and bags.

/**
 * Organizes a list of gifts.
 *
 * @param {string} gifts - The list of gifts to be organized.
 * @returns {string} - The organized representation of the gifts.
 */
function organizeGifts(gifts) {
  let res = "";
  const giftsSplit = gifts.match(/\d+[a-z]/g);

  // Iterate over each gift in the giftsSplit array
  for (const gift of giftsSplit) {
    const quantity = Number(gift.slice(0, -1));
    const giftType = gift.charAt(gift.length - 1);

    // Calculate the number of pallets needed
    const pallets = `[${giftType}]`.repeat(Math.floor(quantity / 50));

    // Calculate the remainder after packing in pallets
    const remainder = quantity % 50;

    // Calculate the number of boxes needed
    const boxes = `{${giftType}}`.repeat(Math.floor(remainder / 10));

    // Calculate the remainder gifts after packing in boxes
    const remainderGifts = giftType.repeat(remainder % 10);

    // Check if there are remainder gifts and create a bag
    const bags = remainderGifts && `(${remainderGifts})`;

    // Concatenate the pallets, boxes, and bags for the current gift
    res += pallets + boxes + bags;
  }

  // Return the organized representation of the gifts
  return res;
}

Enter fullscreen mode Exit fullscreen mode

Community Solutions

Solution by 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

Solution by 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

And that was the challenge for December 8th and its solutions. Give a like if you liked the challenge or the solution! Do you have another alternative solution? Leave it in the comments!

Top comments (0)