**The solution to the** previous challenge

**The solution to the next challenge**

In Santa's workshop, the elves love puzzles 🧠. This year, they have created a special one: a challenge to form a Christmas palindrome.

**A palindrome is a word that reads the same forwards and backward.** The elves want to know if it is possible to form a palindrome by making, at most, one exchange of letters.

Create a function `getIndexsForPalindrome`

that receives a string and returns:

If it is already a palindrome, an empty array.

If it is not possible, null.

If a palindrome can be formed with one change, an array with the two positions (indexes) must be swapped to create it.

For example:

`getIndexsForPalindrome('anna') // []getIndexsForPalindrome('abab') // [0, 1]getIndexsForPalindrome('abac') // nullgetIndexsForPalindrome('aaaaaaaa') // []getIndexsForPalindrome('aaababa') // [1, 3]getIndexsForPalindrome('caababa') // null`

If the palindrome can be formed with different swaps, **always return the first one found.**

In this challenge, our goal is to find a palindrome by swapping two elements of the string and return the indices of those two elements. If a palindrome cannot be found, return an empty array.

- Word (
`word`

): A string with the word to evaluate.

An array of two elements with the indices to change to find the palindrome.

If it's already a palindrome, return an empty array.

If none of the above conditions are met, return

`null`

.

- If multiple palindromes can be formed, always return the first one found.

It can be solved by iterating over each element of the string, and within that iteration, iterating again and swapping elements to compare.

`/** * Returns the indices of characters that need to be reversed in order to make a word a palindrome. * * @param {string} word - The word to check for palindromic properties. * @return {number[] | null} - An array of two indices representing the characters to be reversed, or null if no such indices exist. */function getIndexsForPalindrome(word) { // Check if the given word is already a palindrome const isPalindrome = (s) => s === s.split("").reverse().join(""); // If the word is already a palindrome, return an empty array if (isPalindrome(word)) { return []; } // Iterate through all possible pairs of indices for (let i = 0; i < word.length; i += 1) { for (let j = i + 1; j < word.length; j += 1) { // Create a new word by swapping the characters at indices i and j const newWord = word.substring(0, i) + word[j] + word.substring(i + 1, j) + word[i] + word.substring(j + 1); // If the new word is a palindrome, return the indices i and j if (isPalindrome(newWord)) { return [i, j]; } } } // If no such indices exist, return null return null;}`

Solution by iswilljr:

`function getIndexsForPalindrome(word: string) { const _letters = [...word] const palindrome = word === [..._letters].reverse().join('') let initial: number[] | null = [null, []][+palindrome] let index = 0 let aux = 1 const letters = [_letters, []][+palindrome] let auxLetters = letters.slice(1) for (const letter of letters) { for (const auxLetter of auxLetters) { const w = [...letters] w[index] = auxLetter w[aux] = letter const isPalindrome = +(w.join('') === w.reverse().join('')) const isInitialNull = +(initial == null) const isDifferentIndex = +(index !== aux) const values = [initial, initial, initial, [index, aux]] initial = values[isInitialNull + isDifferentIndex + isPalindrome] aux++ } index++ aux = 1 auxLetters = [[], auxLetters][+(initial == null)] } return initial}`

Solution by Achalogy:

`function getIndexsForPalindrome(word) { let res: any = null for (const a of Array.from({ length: word.length }).keys()) { for (const b of Array.from({ length: word.length }).keys()) { let swapped = [...word] let aux = word[a] swapped[a] = word[b] swapped[b] = aux let left = swapped.slice(0, Math.floor(word.length / 2)).join("") let right = swapped.slice(Math.ceil(word.length / 2)).reverse().join("") res = [ [ null , [ [] , [a, b] ][+((a + b) > 0)] ][+(left == right)] , res ][+!!res] } } return res}`

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

]]>The solution to the previous challenge

The solution to the next challenge

They are turning on the **Christmas lights 🎄** in the city and, as every year, they have to be fixed!

The lights are of two colors: 🔴 and 🟢 . For the effect to be appropriate, **they must always alternate**. That is, if the first light is red, the second must be green, the third red, the fourth green, etc.

We have been asked to write a function `adjustLights`

that, given an array of strings with the color of each light, return the **minimum number** of lights that need to be changed for the colors to alternate.

`adjustLights(['🟢', '🔴', '🟢', '🟢', '🟢'])// -> 1 (you change the fourth light to 🔴)adjustLights(['🔴', '🔴', '🟢', '🟢', '🔴'])// -> 2 (you change the second light to 🟢 and the third to 🔴)adjustLights(['🟢', '🔴', '🟢', '🔴', '🟢'])// -> 0 (they are already alternating)adjustLights(['🔴', '🔴', '🔴'])// -> 1 (you change the second light to 🟢)`

For this exercise, the goal is to find the least number of changes necessary for the lights to alternate. The complexity lies not so much in leaving them alternating, but in finding the fewest number of changes to get to that point.

- Lights (
`lights`

): An array of strings where each color of light goes.

- The minimum number of movements necessary for the lights to alternate.

- It is important to consider that it's not just about alternating the colors, but also finding a way to do it with the least number of movements, as in this case:
`["🟢", "🔴", "🔴", "🟢", "🔴", "🟢", "🔴", "🟢", "🔴"]`

. We start with a green, then a red and subsequently another red, if we change that red to green we realize that the next one is also green and we must also change it, in this case to a red, but then another red would follow... and so on, resulting in a`7`

. The point is that if we simply change the first green to a red and the first red to a green, we would have everything solved with only`2`

changes.

Considering that the colors must alternate, we can reason that if we arrange the array in such a way, it will start with either the red or green color and alternate from there, so we can evaluate both scenarios and count how many changes would be needed, thus mitigating the problem mentioned in the considerations.

`/** * Organizes alternately the lights in an array. * * @param {string[]} lights - The array of lights. * @return {number} Number of changes needed to organize the lights. */function adjustLights(lights) { // Initialize variables to count the necessary changes // both if starting by red or green let redCount = 0; let greenCount = 0; // Iterate over each light color in the array lights.forEach((light, index) => { // Check if the index is even or odd // this in order to count the changes // for both cases, red even and green odd // or green even and red odd if (index % 2) { // We will evaluate the even cases // If it's green, add +1 to green if (light === "🟢") greenCount++; // If it's red, add +1 to red if (light === "🔴") redCount++; } else { // Otherwise for the odd ones // If the light is red, we do the opposite and +1 for green if (light === "🔴") greenCount++; // If the light is green, +1 for red if (light === "🟢") redCount++; } }); // Return the minimum between red and green return Math.min(redCount, greenCount);}`

Solution by Jioh19:

`function adjustLights(lights) { const color = ['🟢', '🔴']; let res = 0; for (const [i, light] of lights.entries()) { res += +(light == color[i % 2]); } return Math.min(res, lights.length - res);}`

Solution by Yasai:

`function adjustLights(lights) { const init = lights[0]; let rev = false; let count1 = 0; let count2 = 0; for (const light of lights) { count1 += rev == (light == init); rev = !rev; } rev = true; for (const light of lights) { count2 += rev == (light == init); rev = !rev; } count1 = Math.min(count1, count2); // Code here return count1;}`

And that was the challenge for December 9th 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!

Solution to the previous challenge

Solution to the next challenge

What an idea *Sam Elfman* has had! He wants to offer a service that creates a **customized Christmas tree 🎄** in a matter of seconds.

To create it, we are given a **string to form the tree** and a **number that indicates its height**.

Each character of the string represents an ornament of the tree, and we use them **cyclically** until we reach the indicated height. At **least, they will always pass us one**.

We must return a multiline **string** with the Christmas tree made with the ornaments, the indicated height **plus a final line with the trunk formed by the character** `|`

in the center and, finally, a new line `\n`

.

For example, if we receive the string "123" and the number `4`

as height, we would have to build this tree:

` 1 2 3 1 2 31 2 3 1 |`

If we receive the string `*@o`

and the number `3`

, the tree we should return is:

` * @ o* @ o |`

Note:

The tree should always be centered, for that reason add blank spaces to the left of each line.

Create spaces only to the left of each line of the tree. Do not leave blank spaces to the right.

The ornaments have a white space between them for separation.

And we're back to drawing! This time it's Christmas trees, which we must draw using the strings passed as parameters and sizing them as indicated.

Ornaments (

`ornaments`

): A string containing the character sequence that will fill the tree.Height (

`height`

): The height and maximum width of the tree.

- A string with the tree's drawing.

We must add spaces at the beginning to give it the shape of a Christmas tree.

At the end, we must insert a line break.

A simple way to complete the challenge is to calculate the total number of characters required, for which we can use mathematics. Once we have this, we can iterate and fill each row of the tree.

`function createChristmasTree(ornaments, height) { let tree = ""; const totalOrnaments = (height * (height + 1)) / 2; const allOrnaments = ornaments.repeat(totalOrnaments); let lastIndex = 0; for (let i = 1; i <= height; i += 1) { const spaces = " ".repeat(height - i); const ornamentRow = allOrnaments .slice(lastIndex, lastIndex + i) .split("") .join(" "); tree += spaces + ornamentRow + "\n"; lastIndex += i; } tree += "|".padStart(height, " ") + "\n"; return tree;}`

Solution by iswilljr:

`function createChristmasTree(ornaments, height) { let result = '' const spaces = ' '.repeat(height - 1) const ornamentsArray = [...ornaments.repeat(height)].join(' ') let currentPosition = 0 for (const index of new Array(height).keys()) { const length = index + 1 const total = currentPosition + length result += spaces.slice(index) + ornamentsArray.slice(currentPosition * 2, total * 2 - 1) + '\n' currentPosition = total % ornaments.length } return result + spaces + '|\n'}`

Solution by yasai:

`function createChristmasTree(ornaments, height) { let tree = ""; let count = 0; // pyramid for (let i = 0; i < height; i++) { let line = ""; // spaces line += " ".repeat(height - i - 1); // ornaments for (let j = 0; j < i + 1; j++) { let dec = ornaments[count]; count++; if (count == ornaments.length) count = 0; if (j == i) { line += `${dec}`; break; } line += `${dec} `; } // add to the tree tree += line + "\n"; } // trunk tree += " ".repeat(height - 1) + "|\n"; return tree; }`

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

]]>The solution to the previous challenge

The solution to the next challenge

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)*/`

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.

- Gifts (
`gifts`

): A string with the quantity of each type of gift.

- A string with the packaged gifts.

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

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;}`

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!

]]>The solution to the previous challenge

The solution to the next challenge

Santa is experimenting with new gift designs and **he needs your help to visualize them in 3D**.

Your task is to write a function that, given a size `n`

(integer), **generates a drawing of a 3D gift** using ASCII characters.

The lines of the gifts are drawn with `#`

and the faces with the symbol passed to us as a parameter:

`drawGift(4, '+')/* #### #++## #++#+#####++##++#+##++######*/drawGift(5, '*')/* ##### #***## #***#*# #***#**######***##***#**##***#*##***#######*/drawGift(1, '^')/*#*/`

Important: We have been told that **there is always a new line at the end of the drawing**.

In this challenge, you have to draw gifts based on the parameters given by the exercise, in the pure style of ASCII Art. In case you haven't fully understood it, here's an example:

` ##### #***## #***#*# #***#**######***##***#**##***#*##***#######`

The above is a 3D rectangle

Where `#`

represents the outline of the rectangle, that is the lines, while the symbol they pass us as a parameter (in this case `*`

) represents the face or surface of the rectangle.

Size (

`size`

): A number representing the size of the gift, it is the length in characters of each line of the gift.Symbol (

`symbol`

): A string that will fill the gift, basically fills each face of the rectangle.

- A string that will look like the drawing of the requested gift.

Always leave a line break at the end of the drawing.

Take into account the spaces in the first half of the drawing, they are important to shape the gift.

The exercise itself is not very complex, the tricky part can be managing the string to draw, but JavaScript offers enough methods for it.

`function drawGift(size, symbol) { // The space at the beginning of the gift let space = size; // Initialize the first part of the gift // the space at the beginning of the gift // and concatenate # with the size of the gift let firstPart = " ".repeat(--space) + "#".repeat(size) + "\n"; // if the size is 1 return the first part `#` if (size === 1) { return firstPart; } // Initialize the second part of the gift //this part is after the half of the gift let secondPart = ""; // loop through the size of the gift for (let i = 1; i < size - 1; i += 1) { // start with the space at the beginning of the gift firstPart += " ".repeat(--space) + // add `#` and the symbol with the size of the gift - 1 "#".padEnd(size - 1, symbol) + // add `#` and fill the space with the symbol "#".padEnd(i + 1, symbol) + // add the break line "#\n"; // The second part is the same but reversed secondPart += "#" + symbol.repeat(size - 2) + "#".padEnd(size - i, symbol) + "#\n"; } // half is `#` with the size of the gift and the symbol with the size of the gift - 2 const half = "#".repeat(size) + symbol.repeat(size - 2) + "#\n"; // return the first part, the half and the second part return firstPart + half + secondPart + "#".repeat(size) + "\n";}`

Solution by marcode24:

`const drawGift = (size, symbol) => { const WRAPPER = '#'; const SPACE = ' '; if (size <= 1) return `${WRAPPER}\n`; const top = [SPACE.repeat(size - 1) + WRAPPER.repeat(size)]; const bottom = [`${WRAPPER.repeat(size)}`]; const middle = `${WRAPPER.repeat(size)}${symbol.repeat(Math.abs(size - 2))}` + `${WRAPPER}\n`; for (let i = 1; i < size; i++) { const line = `${WRAPPER}${symbol.repeat(size - 2)}${WRAPPER}` + `${symbol.repeat(i - 1)}${WRAPPER}`; top.push(SPACE.repeat(size - i - 1) + line); bottom.push(line); } top.pop(); bottom.pop(); top.push(middle); bottom.reverse(); return `${top.join('\n')}${bottom.join('\n')}\n`;};`

Solution by Achalogy:

`function drawGift(size, symbol) { let bgSize = size - 2 bgSize += +!(bgSize + 1) let response = "" let topCenter = "" let bottomCenter = "" for (const a of [...Array.from({ length: bgSize }).keys()]) { const c = "#" + symbol.repeat(bgSize) + "#" + symbol.repeat(a) + "#" bottomCenter = c + "\n" + bottomCenter topCenter += " ".repeat(bgSize - a) + c + "\n" } response = " ".repeat(size - 1) + "#".repeat(size) + "\n" + (topCenter + "#".repeat(size) + symbol.repeat(bgSize) + "#" + "\n" + bottomCenter + "#".repeat(size) + "\n").repeat(+!!(size - 1)) return response}`

And that was the challenge for December 7th and its solutions. Do you have another alternative solution? Leave it in the comments!

]]>Solution to the Solution to the next challengeprevious challenge

Solution to the next challenge

The elves are cataloging Santa's reindeer 🦌 based on the distance they can travel.

For this, they have a text string `movements`

where each character represents the direction of the reindeer's movement:

`>`

= Moves to the right`<`

= Moves to the left`*`

= Can move forward or backward

For example, if the movement is `>>*<`

, it goes to the right twice, then it can go either left or right (whichever maximizes the final traveled distance) and then left.

The elves want to know what the maximum distance the reindeer travels is **after completing all movements.**

**In the previous example, the maximum distance the reindeer travels is** `2`

. It goes to the right twice `+2`

, then with the `*`

it can go to the right again to maximize the distance `+1`

and then it goes to the left `-1`

.

Create a `maxDistance`

function that takes the text string `movements`

and returns **the maximum distance** that the reindeer can travel **in any direction**:

`const movements = '>>*<'const result = maxDistance(movements)console.log(result) // -> 2const movements2 = '<<<>'const result2 = maxDistance(movements2)console.log(result2) // -> 2const movements3 = '>***>'const result3 = maxDistance(movements3)console.log(result3) // -> 5`

Keep in mind that it doesn't matter whether it is to the left or right, the distance is **the absolute value of the maximum distance traveled at the end of the movements**.

Here's the translation of your blog from Spanish to English, leaving the code and links untouched:

Solution to the Challenge #6 of AdventJS 2023 Solution to the previous challenge Solution to the next challenge

{%- # TOC start (generated with https://github.com/derlin/bitdowntoc) -%}

{%- # TOC end -%}

The elves are cataloging Santa's reindeer 🦌 based on the distance they can travel.

For this, they have a string of text movements where each character represents the direction of the reindeer's movement:

`>`

= Moves to the right`<`

= Moves to the left*\= Can move forward or backward For example, if the movement is >>*<, it goes to the right twice, then can go right or left (whichever maximizes the final traveled distance), and then goes to the left.

The elves want to know what is the maximum distance the reindeer travels at the end of all movements.

In the example above, the maximum distance the reindeer travels is 2. It goes to the right two times +2, then with the * can go to the right again to maximize the distance +1, and then goes to the left -1.

Create a function maxDistance that receives the text string movements and returns the maximum distance the reindeer can travel in any direction:

`javascriptCopy codeconst movements = '>>*<'const result = maxDistance(movements)console.log(result) // -> 2const movements2 = '<<<>'const result2 = maxDistance(movements2)console.log(result2) // -> 2const movements3 = '>***>'const result3 = maxDistance(movements3)console.log(result3) // -> 5`

Keep in mind that it doesn't matter if it's to the left or right, the distance is the absolute value of the maximum traveled distance at the end of the movements.

The goal is to find the maximum distance that the reindeers can travel. It doesn't matter if they travel it to the left or right, the point is to find the maximum distance.

- Movements (
`movements`

): A string with the movements, where each character represents the direction of the reindeer's movement.

- The number of the maximum distance that can be reached with those movements

- The maximum distance must be found regardless of whether the movement is to the right or left.

Solving this exercise is not that complicated and, as always, we have many paths and alternatives. A simple approach is to count how many times each movement is repeated and then do the final sum to find the result.

`/** * Calculates the maximum distance based on the given movements. * * @param {string} movements - A string representing the movements. * @returns {number} The maximum distance. */function maxDistance(movements) { // Initialize the directions object with default values const directions = { "<": 0, // Represents left movement ">": 0, // Represents right movement "*": 0, // Represents movement in any direction }; // Count the occurrences of each movement for (const movement of movements) { directions[movement] += 1; } // Calculate the maximum distance // Math.abs() returns the absolute value of a number return Math.abs(directions["<"] - directions[">"]) + directions["*"];}`

Solution by cristianstu:

`function maxDistance(movements) { const a = movements.split(/>/g).length - 1 const b = movements.split(/</g).length - 1 const c = movements.length - a - b; return Math.abs(a - b) + c}`

Solution by jfes29:

`const maxDistance(movements) { let movements1 = movements.replaceAll("*", ""); let movements2 = movements1.replaceAll("<", ""); let movements3 = movements1.replaceAll(">", ""); return movements.length - 2 * Math.min(movements2.length, movements3.length);}`

And that was the challenge for December 6th and its solutions. Do you have another alternative solution? Leave it in the comments!

]]>The solution to the previous challenge

The solution to the next chprevious challengeallenge

Santa 🎅 is testing his new electric sled, the *CyberReindeer*, on a North Pole road. The road is represented by a string of characters, where:

`.`

= Road`S`

= Santa's Sled`*`

= Open barrier`|`

= Closed barrier

Example of a road: `S...|....|.....`

For each unit of time, **the sled moves one position to the right**. If it encounters a closed barrier, it stops until the barrier opens. If it is open, it goes through directly.

**All barriers start closed**, but after 5 units of time, they all open **forever**.

**Create a function that simulates the sled's movement** for a given time and **returns an array** of strings representing the state of the road at each unit of time:

`const road = 'S..|...|..'const time = 10 // units of timeconst result = cyberReindeer(road, time)/* -> result:[ 'S..|...|..', // initial state '.S.|...|..', // sled advances on the road '..S|...|..', // sled advances on the road '..S|...|..', // sled stops at the barrier '..S|...|..', // sled stops at the barrier '...S...*..', // barrier opens, sled advances '...*S..*..', // sled advances on the road '...*.S.*..', // sled advances on the road '...*..S*..', // sled advances on the road '...*...S..', // passes through the open barrier]*/`

The result is an **array where each element shows the road at each unit of time**.

Take into account that **if the sled is in the same position as a barrier**, then it takes its place in the array.

To solve this challenge, we must move the letter `S`

within the string and stop it when it finds a barrier (`|`

). The barrier will open (`*`

) after 5 units of time. We need to store the journey of the letter `S`

in an array until the units of time run out.

Road (

`road`

): The original string through which the sled will make its journey.Time (

`time`

): A number with the units of time.

- An array of the history of the sled's journey

We must stop the sled when it encounters a barrier and store it in history even if it does not move from there.

When the sled passes over an open barrier (

`*`

), it will replace it in the string and once it has passed, the open barrier (`*`

) must be put back.

The initial position of the sled is identified at the beginning. The function iterates for each unit of time, advancing the sled if there is no closed barrier ahead. On the fifth unit of time, all barriers open permanently. The state of the road is updated and saved in an array at each iteration, reflecting the position of the sled and the state of the barriers. The final result is an array showing the state of the road at each moment of the given time.

`/** * Simulates the movement of Santa's sled on a road for a given time. * * @param {string} road - Representation of the road with '.', 'S', '|', and '*'. * @param {number} time - Number of units of time to simulate. * @return {string[]} - Array representing the state of the road at each unit of time. */function cyberReindeer(road, time) { // Stores the state of the road at each unit of time const roadStates = [road]; // Finds the initial position of the sled let sledPosition = road.indexOf("S"); // Character that will be replaced by the sled when it moves let replacedChar = "."; // Iterates for each unit of time, minus one, since the initial state is already included for (let i = 0; i < time - 1; i++) { // Gets the current state of the road let currentRoadState = roadStates[i]; // On the fifth iteration (unit of time 5), all barriers open if (i === 4) { currentRoadState = currentRoadState.replace(/[|]/g, "*"); } // Checks if the next position of the sled is not a closed barrier if (currentRoadState[sledPosition + 1] !== "|") { // Prepares the new sled position // concatenating it to the element that previously was in that position const newSledPosition = `${replacedChar}S`; // Updates the character replaced by the sled before being replaced replacedChar = currentRoadState[sledPosition + 1]; // Builds the new state of the road with the sled moved one position const firstPart = currentRoadState.substring(0, sledPosition); const lastPart = currentRoadState.substring(sledPosition + 2); currentRoadState = firstPart + newSledPosition + lastPart; // Updates the sled position sledPosition += 1; } // Adds the updated state of the road to the array roadStates.push(currentRoadState); } // Returns the array with the state of the road at each unit of time return roadStates;}`

Solution by SantiMenendez19:

`javascriptCopy codefunction cyberReindeer(road, time) { let result = [] let timePassed = 0 let pos = 0 let aux = "." while (time > 0) { result.push(road) time-- timePassed++ if (timePassed >= 5) road = road.replace(/\|/gi, "*") if (road[pos+1] === '.' || road[pos+1] === '*') { road = road.split("") road[pos] = aux aux = road[pos+1] road[pos+1] = "S" road = road.join("") pos++ } } return result}`

Solution by Achalogy:

`javascriptCopy codefunction cyberReindeer(road, time) { let moves = [road] let a = 0 let b = "." for (let i = 1; i < time; i++) { if (i == 5) road = road.replace(/\|/g, "*") const newRoad = road.replace(/S[\.\*]/, `${b}S`) if (newRoad != road) { a++ b = road[a] } road = newRoad moves.push(road) } return moves;}`

And that was the challenge for December 5th and its solutions. Do you have another alternative solution? Leave it in the comments!

]]>The solution to the previous challenge

The solution to the next challenge

In 🎅 Santa's workshop, **some Christmas messages have been written peculiarly**: the words within the brackets must be read backward.

**Santa needs these messages to be correctly formatted.** Your task is to write a function that takes a string and reverses the characters within each pair of parentheses, removing the parentheses as well.

However, bear in mind that there may be nested parentheses, so you should reverse the characters in the correct order.

`const a = decode('hola (odnum)')console.log(a) // hola mundoconst b = decode('(olleh) (dlrow)!')console.log(b) // hello world!const c = decode('sa(u(cla)atn)s')console.log(c) // santaclaus// Step by step:// 1. Reverse the nested -> sa(ualcatn)s// 2. Reverse the remaining one -> santaclaus`

Notes:

The input strings will always be well-formed with parentheses that match correctly, you do not need to validate them.

There should not be any parentheses left in the final message.

The maximum nesting level is 2.

In this exercise, the goal is to reverse the letters that are within parentheses. If there are nested parentheses, you'll need to reorder multiple times, depending on the number of nested levels.

- Message (
`message`

): A string with the message in which we must search and reorder the letters that are inside parentheses.

- The correctly ordered string

There is no need to validate that the parentheses match and are well closed.

All parentheses in the text should be removed.

To cover all cases and considerations, you should start by looking for the last opening parenthesis ( and then match it with the first closing parenthesis ) after the opening one. Extract the letters that are inside and reorder them in reverse.

Then repeat the process with the resulting string, so a while loop can be used to achieve this.

`/** * Decodes a message by reversing the characters between each pair of parentheses. * * @param {string} message - The message to be decoded. * @return {string} - The decoded message. */function decode(message) { // Initialize variables to store the indices of the opening and closing parentheses let init, end; // Loop until there are no more opening and closing parentheses while (init !== -1 || end !== -1) { // Find the index of the last opening parenthesis init = message.lastIndexOf("("); // Find the index of the closing parenthesis after the last opening parenthesis end = message.indexOf(")", init); // Extract the encoded string between the opening and closing parentheses const encoded = message.substring(init, end + 1); // Reverse the characters in the encoded string, excluding the opening and closing parentheses const decoded = encoded.split("").slice(1, -1).reverse().join(""); // Replace the encoded string with the decoded string in the original message message = message.replace(encoded, decoded); } // Return the decoded message return message;}`

Solution by cristianstu:

`function decode(message) { const msg = message.replace(/\(([^()]*)\)/g, (_, match) => match.split('').reverse().join('') ); return msg.includes('(') ? decode(msg) : msg;}`

Solution by TimmyElTaco:

`function decode(message) { let matches = []; while (matches = message.match(/\(([^()]*)\)/)) { matches = matches.map((word) => { return word.split('').reverse().join('') }) let string = matches[0].replace(/[()]/g, ''); message = message.replace(/\(([^()]*)\)/, string); } return message;}`

And that was the challenge for December 4th and its solutions. Do you have another alternative solution? Leave it in the comments!

]]>The solution to the previous challenge

The solution to the next challenge

In Santa's workshop, **a mischievous elf** has been playing around with the gift production line, adding or removing an unplanned step.

You have the original sequence of *original* manufacturing steps and the modified *modified* sequence that may include an extra step or be missing a step.

Your task is to **write a function that identifies and returns the first extra step that was added or removed in the manufacturing chain**. If there is no difference between the sequences, return an empty string.

`const original = 'abcd'const modified = 'abcde'findNaughtyStep(original, modified) // 'e'const original = 'stepfor'const modified = 'stepor'findNaughtyStep(original, modified) // 'f'const original = 'abcde'const modified = 'abcde'findNaughtyStep(original, modified) // ''`

Please, keep in mind:

There will always be one different step or none.

The modification can occur anywhere in the string.

The

*original*steps could be empty

The goal is to write a function that can identify the first difference between two strings, either by an extra char in the string or a missing char.

💡

**Input:**

Original (

`original`

): The original string, from which we must start to find the differences. These are the original steps.Modified (

`modified`

): The modified string to which we must find the first extra char or the first missing char. These are the steps modified by the mischievous elf.

**Output:**

- A string showing the extra or missing char, if not found returns an empty string
`''`

**Considerations**

- The modified sequence must not only contain the chars from the original but also have them in the same order.

You can use a loop to compare char by char in the strings and, upon finding the difference, evaluate whether it is an extra element or a missing element and return it. If the conditions are not met, we return an empty string `''`

.

`/** * Find the first different char between two strings. * * @param {string} original - The original string. * @param {string} modified - The modified string. * @return {string} The first difference between the original and modified string. */function findNaughtyStep(original, modified) { // We start by declaring the index we will be iterating let i = 0; // While i is less than the sizes of both strings // we go through each one to compare them while (i < original.length || i < modified.length) { // If the char from the original string is different from the char in the modified string, // If they are the same we continue iterating and adding 1 to the index if (original[i] !== modified[i]) { // If the original string has more characters than the modified string, // return the char from the original string. // otherwise, return the char from the modified string return original.length > modified.length ? original[i] : modified[i]; } i += 1; } return '';}`

Solution by Achalogy:

`findNaughtyStep(original, modified) { const [lessWords, mostWords] = [original, modified].sort((a, b) => a.length - b.length) return [...mostWords].find((x, i) => lessWords[i] != x) ?? "";}`

Solution by iswilljr:

`findNaughtyStep(original: string, modified: string) { const originalLen = original.length const modifiedLen = modified.length const sequences = { [originalLen]: [original, modified], [modifiedLen]: [modified, original], } const [steps, reference] = sequences[Math.max(originalLen, modifiedLen)] return [...steps].find((step, index) => step !== reference[index]) ?? ''}`

And that was the challenge for December 3rd and its solutions. Do you have another alternative solution? Leave it in the comments!

]]>In Santa's workshop, the elves have a **gift list** they wish to make and a limited set of materials.

*Gifts are strings of text* and *materials are characters*. Your task is to write a function that, given a list of gifts and the available materials, returns a **list of the gifts that can be made**.

A gift can be made if we have all the necessary materials to make it.

`const gifts = ['tren', 'oso', 'pelota']const materials = 'tronesa'manufacture(gifts, materials) // ["tren", "oso"]const gifts = ['juego', 'puzzle']const materials = 'jlepuz'manufacture(gifts, materials) // ["puzzle"]const gifts = ['libro', 'ps5']const materials = 'psli'manufacture(gifts, materials) // []`

We have a string with certain letters that are the materials and an array of words that are the gifts. We must search for the words in which all their letters are found within the string materials.

**Inputs:**

**Gifts (**`gifts`

): An array of strings, where each string represents a gift.**Materials (**`materials`

): A string representing the available materials.

**Output:**

- An array of gifts that can be made using the available materials.

**Considerations**

Each character in a gift's string represents a necessary material.

It is necessary to verify that all characters of a gift are present in the

`materials`

string.Each character in the materials string can be used multiple times, so there is no limit on materials.

To solve this problem, I found two main approaches, iterating over the gifts and materials or using regular expressions.

`jsxCopy code/** * Filters a list of gifts based on the available materials. * * @param {string[]} gifts - The list of gifts to filter. * @param {string} materials - The available materials. * @return {string[]} The filtered list of gifts that can be manufactured. */function manufacture(gifts, materials) { // Use filter to return only the gifts that contain all the materials return gifts.filter((gift) => { // Check if each character in the gift is in the materials for (const char of gift) { // If the character is not in the materials, return false // false means that the gift cannot be manufactured // this stops checking the rest of the characters for better performance if (!materials.includes(char)) { return false; } } // If all the characters are in the materials, return true return true; });}`

This involves creating a regex based on `materials`

that match any combination (including repetition) of characters within `materials`

and nothing else.

💡

Want to learn how to make regex like this? regexlearn.com is an excellent resource to learn!

`jsxCopy code/** * Filters a list of gifts based on the available materials. * * @param {string[]} gifts - The list of gifts to filter. * @param {string} materials - The available materials. * @return {string[]} The filtered list of gifts that can be manufactured. */function manufacture(gifts, materials) { const regex = new RegExp(`^[${materials}]+$`); return gifts.filter((gift) => regex.test(gift));}`

Solution by SantiMenendez19

`jsxCopy codefunction manufacture(gifts, materials) { return gifts.filter(gift => [...gift].every(c => materials.includes(c)))}`

Solution by Savecoders

`jsxCopy codefunction manufacture(gifts, material) { return gifts.filter((gift) => gift.split("").every((matt) => material.includes(matt)) );}`

And that was the challenge for December 2nd and its solutions. Do you have another alternative solution? Leave it in the comments!

]]>On December 1st, AdventJS started a series of challenges to practice and improve as a software developer. It consists of a new programming challenge being enabled every day, from December 1st until Christmas on the 25th. 🎄

In the toy factory of the North Pole, each toy has a unique identification number.

However, due to an error in the toy machine, some numbers have been assigned to more than one toy.

Find the first identification number that has been repeated, **where the second occurrence has the smallest index**!

In other words, if there is more than one repeated number, you must return the number whose second occurrence appears first in the list. If there are no repeated numbers, return -1.

`const giftIds = [2, 1, 3, 5, 3, 2]const firstRepeatedId = findFirstRepeated(giftIds)console.log(firstRepeatedId) // 3// Even though 2 and 3 are repeated// 3 appears second time firstconst giftIds2 = [1, 2, 3, 4]const firstRepeatedId2 = findFirstRepeated(giftIds2)console.log(firstRepeatedId2) // -1// It is -1 since no number is repeatedconst giftIds3 = [5, 1, 5, 1]const firstRepeatedId3 = findFirstRepeated(giftIds3)console.log(firstRepeatedId3) // 5`

**Watch out!** The elves say this is a Google technical test.

The goal is to find the first repeated number where the second occurrence of that number has the lowest possible index in the list. If there are no repeated numbers, -1 will be returned.

- A list of integer numbers (gifts), where each number represents a unique identifier of a toy.

The first identification number is repeated with the lowest index in its second appearance.

`-1`

if there are no repeated numbers.

The first repetition needs to be found, so it's not necessary to iterate more than once.

We need an efficient way to keep track of the numbers already checked.

We will stop execution when we find the first repeated number and return it.

By creating a Set, you can store the repeated values while traversing the array. Each stored element is evaluated, and upon finding a repetition, the answer is returned.

`/** * Finds the first repeated gift in the given array. * * @param {number[]} gifts - The array of gifts to search for repeated items. * @returns {number} - The first repeated gift, or -1 if no repeated gift is found. */function findFirstRepeated(gifts) { // Create a set to store unique gifts const set = new Set(); // Iterate through the gifts array for (const gift of gifts) { // If the gift is already in the set, return it as the first repeated gift if (set.has(gift)) { return gift; } // Add the gift to the set set.add(gift); } // Return -1 if no repeated gift is found return -1;}`

Here are some solutions provided by the community:

Solution by SantiMenendez19

`function findFirstRepeated(gifts) { const repeated = gifts.filter((gift, i) => gifts.indexOf(gift) !== i) return repeated.length > 0 ? repeated[0] : -1}`

Solution by marta-vilaseca

`function findFirstRepeated(gifts) { const unique = new Set(); for (let i = 0; i < gifts.length; i++) { if (unique.has(gifts[i])) { return gifts[i]; } else { unique.add(gifts[i]); } } return -1;}`

Do you have another alternative? Leave it in the comments!

]]>