package main
import (
"fmt"
"os"
"strconv"
"sync"
"time"
)
type TreeNode struct {
left, right *TreeNode
}
func bottomUpTree(depth int) *TreeNode {
if 0 < depth {
return &TreeNode{bottomUpTree(depth - 1), bottomUpTree(depth - 1)}
} else {
return &TreeNode{nil, nil}
}
}
func (node *TreeNode) itemCheck() int {
if node.left == nil {
return 1
} else {
return 1 + node.left.itemCheck() + node.right.itemCheck()
}
}
func loops(ch chan string, max_depth int, min_depth int, depth int) {
check := 0
iterations := 1 << (max_depth - depth + min_depth)
for i := 1; i <= iterations; i++ {
check += bottomUpTree(depth).itemCheck()
}
ch <- fmt.Sprintf("%d\t trees of depth %d\t check: %d\n", iterations, depth, check)
}
func main() {
var wg sync.WaitGroup
n := 0
if len(os.Args) > 1 {
n, _ = strconv.Atoi(os.Args[1])
}
startTime := time.Now()
minDepth := 4
maxDepth := 0
if n < minDepth+2 {
maxDepth = minDepth + 2
} else {
maxDepth = n
}
stretchDepth := maxDepth + 1
check := bottomUpTree(stretchDepth).itemCheck()
fmt.Printf("stretch tree of depth %d\t check: %d\n", stretchDepth, check)
longLivedTree := bottomUpTree(maxDepth)
results := make([]string, (maxDepth-minDepth)/2+1, (maxDepth-minDepth)/2+1)
for depth := minDepth; depth <= maxDepth; depth += 2 {
wg.Add(1)
go func(depth int, minDepth int, maxDepth int) {
iterations := 1 << (maxDepth - depth + minDepth)
check := 0
for i := 1; i <= iterations; i++ {
check += bottomUpTree(depth).itemCheck()
}
results[(depth-minDepth)/2] = fmt.Sprintf("%d\t trees of depth %d\t check: %d\n", iterations, depth, check)
wg.Done()
}(depth, minDepth, maxDepth)
}
wg.Wait()
for i := 0; i < len(results); i++ {
fmt.Print(results[i])
}
fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck())
endTime := time.Now()
elapsed := endTime.Sub(startTime)
fmt.Printf("time: %dms\n", elapsed.Milliseconds())
}