| // +build ignore |
| |
| /* |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| |
| * Neither the name of "The Computer Language Benchmarks Game" nor the |
| name of "The Computer Language Shootout Benchmarks" nor the names of |
| its contributors may be used to endorse or promote products derived |
| from this software without specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /* The Computer Language Benchmarks Game |
| * http://shootout.alioth.debian.org/ |
| * |
| * contributed by The Go Authors. |
| * based on C program by Kevin Carson |
| */ |
| |
| package main |
| |
| import ( |
| "flag" |
| "fmt" |
| ) |
| |
| var n = flag.Int("n", 15, "depth") |
| |
| type Node struct { |
| item int |
| left, right *Node |
| } |
| |
| type Arena struct { |
| head *Node |
| } |
| |
| var arena Arena |
| |
| func (n *Node) free() { |
| if n.left != nil { |
| n.left.free() |
| } |
| if n.right != nil { |
| n.right.free() |
| } |
| n.left = arena.head |
| arena.head = n |
| } |
| |
| func (a *Arena) New(item int, left, right *Node) *Node { |
| if a.head == nil { |
| nodes := make([]Node, 3<<uint(*n)) |
| for i := 0; i < len(nodes)-1; i++ { |
| nodes[i].left = &nodes[i+1] |
| } |
| a.head = &nodes[0] |
| } |
| n := a.head |
| a.head = a.head.left |
| n.item = item |
| n.left = left |
| n.right = right |
| return n |
| } |
| |
| func bottomUpTree(item, depth int) *Node { |
| if depth <= 0 { |
| return arena.New(item, nil, nil) |
| } |
| return arena.New(item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1)) |
| } |
| |
| func (n *Node) itemCheck() int { |
| if n.left == nil { |
| return n.item |
| } |
| return n.item + n.left.itemCheck() - n.right.itemCheck() |
| } |
| |
| const minDepth = 4 |
| |
| func main() { |
| flag.Parse() |
| |
| maxDepth := *n |
| if minDepth+2 > *n { |
| maxDepth = minDepth + 2 |
| } |
| stretchDepth := maxDepth + 1 |
| |
| check := bottomUpTree(0, stretchDepth).itemCheck() |
| fmt.Printf("stretch tree of depth %d\t check: %d\n", stretchDepth, check) |
| |
| longLivedTree := bottomUpTree(0, maxDepth) |
| |
| for depth := minDepth; depth <= maxDepth; depth += 2 { |
| iterations := 1 << uint(maxDepth-depth+minDepth) |
| check = 0 |
| |
| for i := 1; i <= iterations; i++ { |
| t := bottomUpTree(i, depth) |
| check += t.itemCheck() |
| t.free() |
| t = bottomUpTree(-i, depth) |
| check += t.itemCheck() |
| t.free() |
| } |
| fmt.Printf("%d\t trees of depth %d\t check: %d\n", iterations*2, depth, check) |
| } |
| fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck()) |
| } |