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 typea
gifts are packed in two boxes like this:{a}{a}
.Every 5 boxes are stacked on a pallet, represented by
[x]
. For example, 10a
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, 4b
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)
*/
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
- 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;
}
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('');
}
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
}
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)