CodeSignal — Reverse In Parentheses

Today we are going to solve the test from CodeSignal reverseInParentheses, we will take a look at the test from different angles and shows different solutions in javascript.

If you haven’t tried the test yet, please go to CodeSignal and try the test before reading, it will be more interesting that way, always try to solve the test before looking at the solutions 😇.

The code is written in Javascript, but it will be simple enough that you should understand it easily even if you're not a Javascript developer.

You can read the instructions below or on CodeSignal, the task is pretty simple, get a string with parentheses (possibly nested) and reverse the text in the parentheses, but without the parentheses — there are some nice examples for that.

The code starts with an empty function, which recieves a string.

function reverseInParentheses(inputString) {
// TODO
}

Let us see what we actually need to do:
1. Find the pairs of parentheses
2. Find the part of the string we need to reverse
3. Reverse the string
4. Repeat until all parentheses are replaced

Find the pairs

\( : will match a starting parenthesis “(”
[a-zA-Z] : will match english letters
*? : will match any number of characters, but the question mark will match the shortest amount of characters, got when there are a few pairs that need to be matched individually.
\( : will match an ending parenthesis “(”

In order to implement it by code, we can execute the regex we made on the string, if we didn’t get anything then there is no parenthesis to match, if we did, we can get the startIndex which indicate the open parenthesis, and the end index which indicates the location of the closing parenthesis.

function getStartAndEndIndexes(inputString) {
const regularExpression = /\([a-zA-Z]*?\)/;
const execData = regularExpression.exec(inputString);
if(!execData) {
return null;
}
const startIndex = execData.index;
const endIndex = execData.index + execData[0].length - 1;
return {startIndex, endIndex}
}

The other option will be for us to use a loop — honestly, in an interview, I would rather use a loop since I do not trust my knowledge of regex, all we want to do is the same thing, but with a loop, I will not use array functions, to keep the code simple and also because I will be using a break which doesn’t exist in the array functions.

We are initiating variables, startIndex will indicate the location of the open parenthesis, and the endIndex will indicate the location of the closing parenthesis, do notice we keep updating the start until we meet the first end because in case of something like foo(bar(baz))blim we want to first reverse (baz), and only then reverse the (bar(baz)) part.
Once we find a closing parenthesis we can break out of the loop, and make sure we found a parenthesis, if we didn’t we can just return the string with no changes.

function getStartAndEndIndexes(inputString) {
let startIndex = null;
let endIndex = null;
const chars = inputString.split('');
for(let i = 0; i < chars.length; i++) {
const c = chars[i];
if(c === '(') {
startIndex = i;
}
if(c === ')') {
endIndex = i;
break;
}
}
if(startIndex === null || endIndex === null) {
return null
}
return {startIndex, endIndex}
}

Find the part of the string we need to reverse

function reverseParentheses(startIndex, endIndex, inputString) {
// before the parenthesis
const startSegmant = inputString.substring(0, startIndex);
// the parenthesis
const parenthesisSegmant =
inputString.substring(startIndex +1, endIndex);
// after the parenthesis
const endSegmant =
inputString.substring(endIndex + 1, inputString.length);
return startSegmant + reverse(parenthesisSegmant) + endSegmant;
}

Reverse the string

function reverse(string) {
return string.split('').reverse().join('');
}

That being said, in lots of interviews the interviewers don’t like you using native functions 🙄, so here is a solution with a loop… these two code snippets will work the same way.

function reverse(string) {
let newString = '';
for (let i = string.length - 1; i >= 0; i--) {
newString += string[i];
}
return newString;
}

Repeat until all parentheses are replaced

So let’s start with the recursion, we are simply calling the functions we already created, we introduce the break statement when we check if there are indexes, and we keep calling the same function with the new value until it will hit the break statement.

function reverseInParentheses(inputString) {
const indexes = getStartAndEndIndexes(inputString);
if(!indexes) {
return inputString;
}
const {startIndex, endIndex} = indexes;
const newString =
reverseParentheses(startIndex, endIndex, inputString);
return reverseInParentheses(newString);
}

And the loop version of this would be using a while loop to achieve the same thing.

function reverseInParentheses(inputString) {
let indexes = getStartAndEndIndexes(inputString);
while(indexes) {
const {startIndex, endIndex} = indexes;
const newString =
reverseParentheses(startIndex, endIndex, inputString);
inputString = reverseInParentheses(newString);
indexes = getStartAndEndIndexes(inputString);
}
return inputString;
}

Wrapping it up

Full solution:

Software Engineer