From: sgf Date: Wed, 11 May 2022 14:36:32 +0000 (+0300) Subject: tour: Concurrent tree comparison exercise solution. X-Git-Url: https://gitweb.sgf-dma.tk/?a=commitdiff_plain;h=ab6e089c3b85e427d0e6b45e5464aac43b83c9ab;p=go.git tour: Concurrent tree comparison exercise solution. --- diff --git a/tree/go.mod b/tree/go.mod new file mode 100644 index 0000000..6d1cf5c --- /dev/null +++ b/tree/go.mod @@ -0,0 +1,5 @@ +module tree + +go 1.17 + +require golang.org/x/tour v0.1.0 diff --git a/tree/go.sum b/tree/go.sum new file mode 100644 index 0000000..cde48ea --- /dev/null +++ b/tree/go.sum @@ -0,0 +1,2 @@ +golang.org/x/tour v0.1.0 h1:OWzbINRoGf1wwBhKdFDpYwM88NM0d1SL/Nj6PagS6YE= +golang.org/x/tour v0.1.0/go.mod h1:DUZC6G8mR1AXgXy73r8qt/G5RsefKIlSj6jBMc8b9Wc= diff --git a/tree/tree.go b/tree/tree.go new file mode 100644 index 0000000..c272961 --- /dev/null +++ b/tree/tree.go @@ -0,0 +1,99 @@ +package main + +import ( + "fmt" + "strconv" + //"bytes" + "strings" + + "golang.org/x/tour/tree" +) + +// Walk walks the tree t sending all values +// from the tree to the channel ch. +func Walk(m, wm string, t *tree.Tree, ch chan int) { + if t == nil { + return + } + fmt.Printf("[%v] node %v start\n", m, t.Value) + Walk(m, wm, t.Left, ch) + fmt.Printf("[%v] node %v Left done\n", m, t.Value) + waiting := false + +out: + for { + select { + case ch <- t.Value: + if waiting { + fmt.Println() + waiting = false + } + fmt.Printf("[%v] node %v sent\n", m, t.Value) + break out + default: + if !waiting { + fmt.Printf("[%v] node %v waiting", m, t.Value) + waiting = true + } else { + fmt.Printf(wm) + } + } + } + + Walk(m, wm, t.Right, ch) + fmt.Printf("[%v] node %v Right DONE\n", m, t.Value) +} + +func walkTree (m, wm string, t *tree.Tree, ch chan int) { + Walk(m, wm, t, ch) + fmt.Printf("Finish\n") + close(ch) +} + +// Same determines whether the trees +// t1 and t2 contain the same values. +//func Same(t1, t2 *tree.Tree) bool + +func Same(t1, t2 *tree.Tree) bool { + ch1 := make(chan int) + ch2 := make(chan int) + + go walkTree("t1", ".", t1, ch1) + go walkTree("t2", "*", t2, ch2) + fmt.Printf("Comparing..\n") + fmt.Println(t1) + fmt.Println(t2) + + i := 0 + for ; i < 10; i++ { + v1 := <- ch1 + v2 := <- ch2 + if v1 != v2 { + fmt.Printf("Trees differ at %v / %v\n", v1, v2) + return false + } + } + fmt.Printf("Trees are identical\n") + return true +} + +func main() { + ch := make(chan int) + t1 := tree.New(1) + fmt.Println(t1) + + go walkTree("t1", ".", t1, ch) + //var res bytes.Buffer + var res strings.Builder + for x := range ch { + fmt.Printf("\n%v\n", x) + res.Write([]byte(strconv.Itoa(x))) + } + fmt.Printf("Result: %v\n", res.String()) + + t2 := tree.New(1) + + b := Same(t1, t2) + fmt.Println(b) +} +