Finding all combinations of well-formed brackets

24,828

Solution 1

Took a crack at it.. C# also.

public void Brackets(int n) {
    for (int i = 1; i <= n; i++) {
        Brackets("", 0, 0, i);
    }
}

private void Brackets(string output, int open, int close, int pairs) {
    if((open==pairs)&&(close==pairs)) {
        Console.WriteLine(output);
    } else {
        if(open<pairs)
            Brackets(output + "(", open+1, close, pairs);
        if(close<open)
            Brackets(output + ")", open, close+1, pairs);
    }
}

The recursion is taking advantage of the fact that you can never add more opening brackets than the desired number of pairs, and you can never add more closing brackets than opening brackets..

Solution 2

Python version of the first voted answer.

def foo(output, open, close, pairs):
    if open == pairs and close == pairs:
        print output
    else:
        if open<pairs:
            foo(output+'(', open+1, close, pairs)
        if close<open:
            foo(output+')', open, close+1, pairs)

foo('', 0, 0, 3)

Solution 3

F#:

Here is a solution that, unlike my previous solution, I believe may be correct. Also, it is more efficient.

#light

let brackets2 n =
    let result = new System.Collections.Generic.List<_>()
    let a = Array.create (n*2) '_'
    let rec helper l r diff i =
        if l=0 && r=0 then
            result.Add(new string(a))
        else
            if l > 0 then
                a.[i] <- '('
                helper (l-1) r (diff+1) (i+1)
            if diff > 0 then
                a.[i] <- ')'
                helper l (r-1) (diff-1) (i+1)
    helper n n 0 0
    result

Example:

(brackets2 4) |> Seq.iter (printfn "%s")

(*
(((())))
((()()))
((())())
((()))()
(()(()))
(()()())
(()())()
(())(())
(())()()
()((()))
()(()())
()(())()
()()(())
()()()()
*)

Solution 4

The number of possible combinations is the Catalan number of N pairs C(n).

This problem was discussed on the joelonsoftware.com forums pretty exentsively including iterative, recursive and iterative/bitshifting solutions. Some pretty cool stuff there.

Here is a quick recursive solution suggested on the forums in C#:

C#

public void Brackets(int pairs) {
    if (pairs > 1) Brackets(pairs - 1);
    char[] output = new char[2 * pairs];

    output[0] = '(';
    output[1] = ')';

    foo(output, 1, pairs - 1, pairs, pairs);
    Console.writeLine();
}

public void foo(char[] output, int index, int open, int close,
        int pairs) {
    int i;

    if (index == 2 * pairs) {
        for (i = 0; i < 2 * pairs; i++)
            Console.write(output[i]);
        Console.write('\n');
        return;
    }

    if (open != 0) {
        output[index] = '(';
        foo(output, index + 1, open - 1, close, pairs);
    }

    if ((close != 0) && (pairs - close + 1 <= pairs - open)) {
        output[index] = ')';
        foo(output, index + 1, open, close - 1, pairs);
    }

    return;
}

Brackets(3);

Output:
()
(()) ()()
((())) (()()) (())() ()(()) ()()()

Solution 5

Here's another F# solution, favoring elegance over efficiency, although memoization would probably lead to a relatively well performing variant.

let rec parens = function
| 0 -> [""]
| n -> [for k in 0 .. n-1 do
        for p1 in parens k do
        for p2 in parens (n-k-1) ->
          sprintf "(%s)%s" p1 p2]

Again, this only yields a list of those strings with exactly n pairs of parens (rather than at most n), but it's easy to wrap it.

Share:
24,828
aleemb
Author by

aleemb

I am a web development junkie and love the whole stack. SOreadytohelp

Updated on January 11, 2022

Comments

  • aleemb
    aleemb almost 2 years

    This came up while talking to a friend and I thought I'd ask here since it's an interesting problem and would like to see other people's solutions.

    The task is to write a function Brackets(int n) that prints all combinations of well-formed brackets from 1...n. For Brackets(3) the output would be

    ()
    (())  ()()   
    ((()))  (()())  (())()  ()(())  ()()()