Skip to content

Instantly share code, notes, and snippets.

@bunyk
Created Mar 18, 2018
Embed
What would you like to do?
Баланс дужок
package main
import (
"fmt"
"log"
"os"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("Please specify a file to read")
}
for page := range Read(os.Args[1]) {
if page.Namespace != 0 {
continue // skip all namespaces except main
}
if page.Redirect != nil {
continue // skip redirects
}
err := checkBalance([]rune(page.Text))
if err != nil {
fmt.Println(page.Title, err)
}
}
}
type Stack struct {
contents []rune
}
func (s Stack) String() string {
return string(s.contents)
}
func (s Stack) Length() int {
return len(s.contents)
}
func (s *Stack) Push(v rune) {
s.contents = append(s.contents, v)
}
func (s *Stack) Pop() (rune, error) {
l := len(s.contents)
if l == 0 {
return 0, fmt.Errorf("Stack if empty")
}
r := s.contents[l-1]
s.contents = s.contents[:l-1]
return r, nil
}
func checkBalance(text []rune) error {
stack := Stack{}
for i, r := range text {
if (r == '[' || r == '{') {
stack.Push(r)
}
if (r == ']' || r == '}') {
s, err := stack.Pop()
if err != nil {
return fmt.Errorf(
"Закриваюча дужка %s без відкриваючої до неї біля %#v",
string([]rune{r}),
string(text[max(0, i - 20): min(len(text), i + 20)]),
)
}
if (
(r == ']' && s != '[') ||
(r == '}' && s != '{')) {
return fmt.Errorf(
"Біля %#v закривається %s, але була відкрита %s",
string(text[max(0, i - 20): min(len(text), i + 20)]),
string([]rune{r}), string([]rune{s}),
)
}
}
}
if stack.Length() != 0 {
return fmt.Errorf("До кінця сторінки не закриті наступні дужки %s", stack)
}
return nil
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment