github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/test/bench/garbage/peano.go (about) 1 // run 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package main 8 9 import ( 10 "fmt" 11 "runtime" 12 "time" 13 ) 14 15 type Number struct { 16 next *Number 17 } 18 19 // ------------------------------------- 20 // Peano primitives 21 22 func zero() *Number { return nil } 23 24 func is_zero(x *Number) bool { return x == nil } 25 26 func add1(x *Number) *Number { 27 e := new(Number) 28 e.next = x 29 return e 30 } 31 32 func sub1(x *Number) *Number { return x.next } 33 34 func add(x, y *Number) *Number { 35 if is_zero(y) { 36 return x 37 } 38 39 return add(add1(x), sub1(y)) 40 } 41 42 func mul(x, y *Number) *Number { 43 if is_zero(x) || is_zero(y) { 44 return zero() 45 } 46 47 return add(mul(x, sub1(y)), x) 48 } 49 50 func fact(n *Number) *Number { 51 if is_zero(n) { 52 return add1(zero()) 53 } 54 55 return mul(fact(sub1(n)), n) 56 } 57 58 // ------------------------------------- 59 // Helpers to generate/count Peano integers 60 61 func gen(n int) *Number { 62 if n > 0 { 63 return add1(gen(n - 1)) 64 } 65 66 return zero() 67 } 68 69 func count(x *Number) int { 70 if is_zero(x) { 71 return 0 72 } 73 74 return count(sub1(x)) + 1 75 } 76 77 func check(x *Number, expected int) { 78 var c = count(x) 79 if c != expected { 80 panic(fmt.Sprintf("error: found %d; expected %d", c, expected)) 81 } 82 } 83 84 // ------------------------------------- 85 // Test basic functionality 86 87 func verify() { 88 check(zero(), 0) 89 check(add1(zero()), 1) 90 check(gen(10), 10) 91 92 check(add(gen(3), zero()), 3) 93 check(add(zero(), gen(4)), 4) 94 check(add(gen(3), gen(4)), 7) 95 96 check(mul(zero(), zero()), 0) 97 check(mul(gen(3), zero()), 0) 98 check(mul(zero(), gen(4)), 0) 99 check(mul(gen(3), add1(zero())), 3) 100 check(mul(add1(zero()), gen(4)), 4) 101 check(mul(gen(3), gen(4)), 12) 102 103 check(fact(zero()), 1) 104 check(fact(add1(zero())), 1) 105 check(fact(gen(5)), 120) 106 } 107 108 // ------------------------------------- 109 // Factorial 110 111 func main() { 112 t0 := time.Now() 113 verify() 114 for i := 0; i <= 9; i++ { 115 print(i, "! = ", count(fact(gen(i))), "\n") 116 } 117 runtime.GC() 118 t1 := time.Now() 119 120 gcstats("BenchmarkPeano", 1, t1.Sub(t0)) 121 }