tour: Concurrent tree comparison exercise solution.
authorsgf <sgf.dma@gmail.com>
Wed, 11 May 2022 14:36:32 +0000 (17:36 +0300)
committersgf <sgf.dma@gmail.com>
Wed, 11 May 2022 14:40:10 +0000 (17:40 +0300)
tree/go.mod [new file with mode: 0644]
tree/go.sum [new file with mode: 0644]
tree/tree.go [new file with mode: 0644]

diff --git a/tree/go.mod b/tree/go.mod
new file mode 100644 (file)
index 0000000..6d1cf5c
--- /dev/null
@@ -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 (file)
index 0000000..cde48ea
--- /dev/null
@@ -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 (file)
index 0000000..c272961
--- /dev/null
@@ -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)
+}
+