diff --git a/src/chapter8/problem9.go b/src/chapter8/problem9.go new file mode 100644 index 0000000..fd9bd01 --- /dev/null +++ b/src/chapter8/problem9.go @@ -0,0 +1,32 @@ +package chapter8 + +// Parens returns all valid parentheses by given number of pairs +func Parens(num int) []string { + var ( + res []string + bs []byte + ) + + ParensR(num, 0, 0, bs, &res) + + return res +} + +// ParensR adds valid parentheses with recursion +func ParensR(num, leftCnt, rightCnt int, bs []byte, res *[]string) { + if num < leftCnt || num < rightCnt { + return + } + if num == leftCnt && num == rightCnt { + *res = append(*res, string(bs)) + return + } + + if leftCnt < num { + ParensR(num, leftCnt+1, rightCnt, append(bs, '('), res) + } + + if rightCnt < num && rightCnt < leftCnt { + ParensR(num, leftCnt, rightCnt+1, append(bs, ')'), res) + } +} diff --git a/src/chapter8/problem9_test.go b/src/chapter8/problem9_test.go new file mode 100644 index 0000000..6241964 --- /dev/null +++ b/src/chapter8/problem9_test.go @@ -0,0 +1,56 @@ +package chapter8 + +import ( + "reflect" + "testing" +) + +func TestParens(t *testing.T) { + tests := map[string]struct { + in int + out []string + }{ + "Input is -1": { + in: -1, + out: []string(nil), + }, + "Input is 0": { + in: 0, + out: []string{ + "", + }, + }, + "Input is 1": { + in: 1, + out: []string{ + "()", + }, + }, + "Input is 2": { + in: 2, + out: []string{ + "(())", + "()()", + }, + }, + "Input is 3": { + in: 3, + out: []string{ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()", + }, + }, + } + + for k, test := range tests { + t.Run(k, func(t *testing.T) { + out := Parens(test.in) + if !reflect.DeepEqual(out, test.out) { + t.Errorf("actual=%+v expected=%+v", out, test.out) + } + }) + } +}