3

Background

I am following a course on Udemy which goes over all of the ES6 features. In one of the lessons the instructor talks about using the reduce helper method to solve the popular balance parenthesis interview question.

I can solve this without the reduce method. Although with the reduce method it does get the job done in less code. I have been asked to find the depth of the parenthesis in an interview before and was wondering if this could all be done in the same method using reduce.

I do not know why this addition to the question confuses me so much but I would like to learn.

Problem

I have been trying to figure it out for a while and it might be my lack of understanding how reduce works.

Example

This uses reduce to return true of false regarding if the parenthesis or open and closed evenly.

function balanceParens(string) {
    return !string.split("").reduce((counter, char) => {
        // Handle if parens open and close out of order
        if (counter < 0) { return counter; }
        // Add 1 for each open in order
        if (char === "(") { return ++counter; }
        // subtract 1 for each close in order
        if (char === ")") { return --counter; }
        // handle use case if char is not a paren
        return counter;
    }, 0);
}
console.log(balanceParens("((()))"));

Question

How would I return the max depth of the parenthesis using the reduce helper method.

wuno
  • 9,547
  • 19
  • 96
  • 180
  • Actually reduce was introduced in ES5… – Bergi Jul 06 '17 at 18:01
  • How would you solve the problem without `reduce`? If you can post your loop code, we can help you transform it into `reduce`. – Bergi Jul 06 '17 at 18:01
  • Yes it was introduced in es5. But the course if over es6 and this was just something he was talking about in the es6 course. – wuno Jul 06 '17 at 18:03
  • @Bergi when I get home I can post a solution not using reduce. But it will be a few hours. – wuno Jul 06 '17 at 18:04
  • 3
    Generally when you have something that fits the pattern of `.reduce()` but you need multiple values, you just use an object as the reduce target. – Pointy Jul 06 '17 at 18:05
  • @Bergi TIL reduce was in spec version 5.1 :P – Andrew Li Jul 06 '17 at 18:05

3 Answers3

3

You could maintain current depth and max depth while reducing.

function maxDepth(string) {
    return string.split("").reduce(({current, max}, char) => {
        // Handle if parens open and close out of order
        if (current < 0) return {current, max}
        // Add 1 for each open in order
        if (char === "(") return { current: current + 1, max: Math.max(max, current + 1)}
        // subtract 1 for each close in order
        if (char === ")") return { current: current - 1, max}
        return {current, max}
    }, {current: 0, max: 0}).max;
}
console.log(maxDepth("(((()))(((())))()(((((()))))))"));
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
1

Here is a compact version that returns NaN when the parentheses are not balanced. It uses nested functions in a functional style:

function maxDepth(string) {
    return ( ([depth, max]) => depth ? NaN : max )
        ([...string].reduce(([depth, max], ch) => 
            (newDepth => [newDepth, newDepth < 0 ? NaN : Math.max(max, newDepth)])
                 (depth + (ch === "(") - (ch === ")"))
        , [0, 0]));
}
console.log(maxDepth("(((()))(((())))()(((((()))))))"));
trincot
  • 317,000
  • 35
  • 244
  • 286
0

This should answer it!

function balanceParens(string) {
    let max = 0;
    let res = string.split("").reduce((counter, char) => {
        // Handle if parens open and close out of order
        if (counter < 0) { 
          return counter;
        }
        // Add 1 for each open in order
        if (char === "(") {
          if(++counter > max) {
            max = counter;
          }
          return counter;
        }
        // subtract 1 for each close in order
        if (char === ")") {
          return --counter;
        }
        // handle use case if char is not a paren
        return counter;
    }, 0);
    console.log("Max depth was :", max);
    return !res;
}
console.log(balanceParens("((()(((())))))((((()))))"));
Aftab Khan
  • 3,853
  • 1
  • 21
  • 30