Skip to content

Commit 75b99a2

Browse files
authored
fix: Add docs and tests to IsBalanced (#326)
1 parent 5459f18 commit 75b99a2

File tree

2 files changed

+130
-40
lines changed

2 files changed

+130
-40
lines changed
Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,62 @@
1-
// The nested brackets problem is a problem that determines if a sequence of
2-
// brackets are properly nested. A sequence of brackets s is considered properly nested
1+
// Package nested_brackets provides functions for testing
2+
// strings propper brackets nesting.
3+
package nested_brackets
4+
5+
// IsBalanced returns true if provided input string is properly nested.
6+
//
7+
// Input is a sequence of brackets: '(', ')', '[', ']', '{', '}'.
8+
//
9+
// A sequence of brackets `s` is considered properly nested
310
// if any of the following conditions are true:
4-
// - s is empty
5-
// - s has the form (U) or [U] or {U} where U is a properly nested string
6-
// - s has the form VW where V and W are properly nested strings
11+
// - `s` is empty;
12+
// - `s` has the form (U) or [U] or {U} where U is a properly nested string;
13+
// - `s` has the form VW where V and W are properly nested strings.
14+
//
715
// For example, the string "()()[()]" is properly nested but "[(()]" is not.
8-
// The function called isBalanced takes as input a string which is a sequence of brackets and
9-
// returns true if input is nested and false otherwise.
10-
//note that only an even number of brackets can be properly nested
11-
12-
package nested_brackets
16+
//
17+
// **Note** Providing characters other then brackets would return false,
18+
// despite brackets sequence in the string. Make sure to filter
19+
// input before useage.
20+
func IsBalanced(input string) bool {
21+
if len(input) == 0 {
22+
return true
23+
}
1324

14-
// IsBalanced function which checks whether the number of brackets are balanced
15-
func IsBalanced(input string) string {
1625
if len(input)%2 != 0 {
17-
return input + "is not balanced."
26+
return false
1827
}
19-
if len(input) > 0 {
20-
var stack []byte
21-
for i := 0; i < len(input); i++ {
22-
if input[i] == '(' || input[i] == '{' || input[i] == '[' {
23-
stack = append(stack, input[i])
24-
} else {
25-
if len(stack) > 0 {
26-
pair := string(stack[len(stack)-1]) + string(input[i])
27-
stack = stack[:len(stack)-1]
2828

29-
if pair != "[]" && pair != "{}" && pair != "()" {
30-
return input + " is not balanced."
31-
}
32-
} else {
33-
return input + " is not balanced."
29+
// Brackets such as '{', '[', '(' are valid UTF-8 characters,
30+
// which means that only one byte is required to code them,
31+
// so can be stored as bytes.
32+
var stack []byte
33+
34+
for i := 0; i < len(input); i++ {
35+
if input[i] == '(' || input[i] == '{' || input[i] == '[' {
36+
stack = append(stack, input[i])
37+
} else {
38+
if len(stack) > 0 {
39+
pair := string(stack[len(stack)-1]) + string(input[i])
40+
stack = stack[:len(stack)-1]
41+
42+
if pair != "[]" && pair != "{}" && pair != "()" {
43+
// This means that two types of brackets has
44+
// been mixed together, for example "([)]",
45+
// which makes seuqence invalid by definition.
46+
return false
3447
}
48+
} else {
49+
// This means that closing bracket is encountered
50+
// before opening one, which makes all sequence
51+
// invalid by definition.
52+
return false
3553
}
3654
}
37-
if len(stack) == 0 {
38-
return input + " is balanced."
39-
}
4055
}
41-
return "Please enter a sequence of brackets."
42-
}
43-
44-
// func main() {
45-
// reader := bufio.NewReader(os.Stdin)
46-
// fmt.Print("Enter sequence of brackets: ")
47-
// text, _ := reader.ReadString('\n')
4856

49-
// text = strings.TrimSpace(text)
50-
// fmt.Println(isBalanced(text))
51-
// }
57+
// If sequence is properly nested, all elements in stack
58+
// has been paired with closing elements. If even one
59+
// element has not been paired with a closing bracket,
60+
// means that sequence is invalid by definition.
61+
return len(stack) == 0
62+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package nested_brackets
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestIsBalancedSimple(t *testing.T) {
8+
input := "{[()]}"
9+
10+
got := IsBalanced(input)
11+
want := true
12+
13+
if got != want {
14+
t.Errorf("\nInput: %s\nGot: %v\nWant: %v\n", input, got, want)
15+
}
16+
}
17+
18+
func TestIsBalancedFalty(t *testing.T) {
19+
input := "{([()]}"
20+
21+
got := IsBalanced(input)
22+
want := false
23+
24+
if got != want {
25+
t.Errorf("\nInput: %s\nGot: %v\nWant: %v\n", input, got, want)
26+
}
27+
}
28+
29+
func TestIsBalancedHandlesEmpty(t *testing.T) {
30+
input := ""
31+
32+
got := IsBalanced(input)
33+
want := true
34+
35+
if got != want {
36+
t.Errorf("\nInput: %s\nGot: %v\nWant: %v\n", input, got, want)
37+
}
38+
}
39+
40+
func TestIsBalancedHandlesOneChar(t *testing.T) {
41+
input := "{"
42+
43+
got := IsBalanced(input)
44+
want := false
45+
46+
if got != want {
47+
t.Errorf("\nInput: %s\nGot: %v\nWant: %v\n", input, got, want)
48+
}
49+
}
50+
51+
func TestIsBalancedHandlesNonBracketsCorrectly(t *testing.T) {
52+
input := "aaaa"
53+
54+
got := IsBalanced(input)
55+
want := false
56+
57+
if got != want {
58+
t.Errorf("\nInput: %s\nGot: %v\nWant: %v\n", input, got, want)
59+
}
60+
}
61+
62+
func TestIsBalancedHandlesOrdering(t *testing.T) {
63+
input := "([)]"
64+
65+
got := IsBalanced(input)
66+
want := false
67+
68+
if got != want {
69+
t.Errorf("\nInput: %s\nGot: %v\nWant: %v\n", input, got, want)
70+
}
71+
}
72+
73+
func BenchmarkIsBalanced(b *testing.B) {
74+
input := "{[()]}"
75+
76+
for i := 0; i < b.N; i++ {
77+
IsBalanced(input)
78+
}
79+
}

0 commit comments

Comments
 (0)