Skip to content

Instantly share code, notes, and snippets.

@Aadithya-V
Last active May 12, 2023 16:48
Show Gist options
  • Save Aadithya-V/c9df0a41d189665c346f95d9faf55aa9 to your computer and use it in GitHub Desktop.
Save Aadithya-V/c9df0a41d189665c346f95d9faf55aa9 to your computer and use it in GitHub Desktop.
Equivalence Of Binary Trees- using concurrency of Go; Go Tour Exercise
package main
import (
"fmt"
"sync"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan<- int) {
if t == nil {
return
}
Walk(t.Left, ch)
Walk(t.Right, ch)
ch <- t.Value
//fmt.Println(t.Value) // uncomment for debugging puroposes
}
type SafeEqMap struct {
mu sync.Mutex
m map[int]struct{} // the element's value is not used for our purposes.
}
// adds i to SafeEqMap-
// 1) if i is not already in SafeEqMap, adds directly
// 2) if i already in SafeEqMap, pops i
// the absence of any element at the end indicates equivalence.
func (sm *SafeEqMap) EqAdd(key int) {
sm.mu.Lock()
defer sm.mu.Unlock()
if _, ok := sm.m[key]; ok == true {
delete(sm.m, key)
return
}
sm.m[key] = struct{}{}
}
// Returns true if map is empty, ie, equivalence achieved.
// Else returns false.
// WARNING: Only execute when there are no more elements to add using EqAdd()
func (sm *SafeEqMap) IsEq() bool {
sm.mu.Lock()
defer sm.mu.Unlock()
if len(sm.m) == 0 {
return true
} else {
return false
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
ch1 := make(chan int, 10)
ch2 := make(chan int, 10)
go func() {
defer close(ch1)
Walk(t1, ch1)
} ()
go func() {
defer close(ch2)
Walk(t2, ch2)
} ()
sm := SafeEqMap{m: make(map[int]struct{})}
for {
select {
case i, ok := <-ch1:
if ok {
sm.EqAdd(i)
}
if !ok {
ch1 = nil
}
case j, ok := <-ch2:
if ok {
sm.EqAdd(j)
}
if !ok {
ch2 = nil
}
}
if ch1 == nil && ch2 == nil {
break
}
}
return sm.IsEq()
}
func main() {
t1 := tree.New(1) // Generates a binary tree. See: https://godoc.org/golang.org/x/tour/tree#Tree
t2 := tree.New(1) // Try passing in another int as the paramenter for an unequivalent binary tree
fmt.Print(Same(t1, t2))
}
@Aadithya-V
Copy link
Author

Elegant, isn't it? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment