AdventJS Challenge 4, midudev 2023 - Turn the parentheses around
Tags: javascript, adventofcode, challenge, programming
Published: 2023-12-05 15:29:07

## Instructions for the challenge:
In 🎅 Santa's workshop, some Christmas messages have been written in a peculiar way: the words within the brackets must be read backwards.

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 mundo

const 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.


## My solution AdventJS Challenge day 4

Before explaining the solution, I identified that to solve this problem, I needed a complex regular expression to find patterns of open and closed parentheses.

I'm not good with regular expressions (in fact, I'm quite bad), so for this particular case, I sought help from ChatGPT. Now, I'll proceed to explain the solution.

```js
function decode(message) {
  const regex = /\(([^()]+)\)/
  let match = message.match(regex)
  
  while (match) {
    const reversed = match[1].split('').reverse().join('')
    message = message.replace(regex, reversed)
    match = message.match(regex)
  }

  return message
}
```

1.  Define a regular expression `/\(([^()]+)\)/g`: `\(` and `\)` match open and closed parentheses, respectively. `([^()]+)` is a capture group that matches any character except parentheses, at least once. The `g` modifier indicates global search, meaning it looks for all matches rather than stopping after the first.
    
2.  Initialize the variable `match` using `message.match(regex)`. This finds the first match of the regular expression in the message and stores information about the match in the variable `match`.
    
3.  Start a `while` loop that continues as long as there are matches (`match !== null`).
    
4.  Inside the loop, you can print the current match to the console with `console.log(match)` (this can be helpful for understanding the process). Inspecting the console with `match` may return something like this: `[ '(cla)', 'cla', index: 4, input: 'sa(u(cla)atn)s', groups: undefined ]`. From these data, we need the value at index 1 to reverse it.
    
5.  Reverse the content of the found substring using `split('')`, `reverse()`, and `join('')`. This is stored in the variable `reversed`.
    
6.  Replace the original substring (`message`) with its reversed version in the message using `message.replace(regex, reversed)`. This finds the first match and replaces it with the value of `reversed`.
    
7.  Assign a new value to the `match` variable using the updated value stored in `message`.
    
8.  The loop continues until there are no more matches.
    
9.  Finally, return the modified message.

## Previous Challenges:

1.  [Challenge 1 advent JS 2023](https://dev.to/juneikerc/challenge-1-solution-adventjs-2023-by-midudev-104c)
2.  [Challenge 2 advent JS 2023](https://dev.to/juneikerc/challenge-2-advent-js-2023-by-midudev-4p6f)
3. [Challenge 3 advent JS 2023](https://dev.to/juneikerc/challenge-3-adventjs-midudev-the-naughty-elf-11pb)

### Useful Resources

-   [MDN Regular Expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions)
-   [While Loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while)
-   [Reverse String](https://juneikerc.com/en/code-blog/javascript/reverse-string/)