diff options
| author | Rob Pike <r@golang.org> | 2009-08-07 15:28:46 -0700 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2009-08-07 15:28:46 -0700 |
| commit | 49251393e9836da3f83bf674d249736814c28fe0 (patch) | |
| tree | 14f7a660b792e5702c83649edd7f304f00ac4572 /test/bench/chameneosredux.go | |
| parent | 8f188ef3ddff58686110cccb4ab52863cc00bd66 (diff) | |
| download | golang-49251393e9836da3f83bf674d249736814c28fe0.tar.gz | |
chameneos
R=rsc
DELTA=514 (513 added, 0 deleted, 1 changed)
OCL=32898
CL=32910
Diffstat (limited to 'test/bench/chameneosredux.go')
| -rw-r--r-- | test/bench/chameneosredux.go | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/test/bench/chameneosredux.go b/test/bench/chameneosredux.go new file mode 100644 index 000000000..6ca085ac7 --- /dev/null +++ b/test/bench/chameneosredux.go @@ -0,0 +1,202 @@ +/* +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. + */ + +package main + +import ( + "flag"; + "fmt"; + "os"; +) + +var n = flag.Int("n", 600, "count") + +type Color int + +const ( + blue Color = iota; + red; + yellow; +) + +func (c Color) String() string { + return []string{"blue", "red", "yellow"}[c] +} + +func complement(c1, c2 Color) Color { + switch c1 << 2 | c2 { + case blue << 2 | blue: + return blue + case blue << 2 | red: + return yellow + case blue << 2 | yellow: + return red + case red << 2 | blue: + return yellow + case red << 2 | red: + return red + case red << 2 | yellow: + return blue + case yellow << 2 | blue: + return red + case yellow << 2 | red: + return blue + case yellow << 2 | yellow: + return yellow + } + fmt.Println("invalid colors", c1, c2); + os.Exit(2); + return 0 +} + +func printColors(c1, c2 Color) { + fmt.Printf("%s + %s -> %s\n", c1, c2, complement(c1, c2)); +} + +func printColorTable() { + printColors(blue, blue); + printColors(blue, red); + printColors(blue, yellow); + printColors(red, blue); + printColors(red, red); + printColors(red, yellow); + printColors(yellow, blue); + printColors(yellow, red); + printColors(yellow, yellow); +} + +type Referee struct { + rendezCount int; + cham []*Chameneos; + rendez chan *Chameneos; + done chan int; +} + +func NewReferee() *Referee { + ref := new(Referee); + ref.cham = make([]*Chameneos, 0, 100); + ref.rendez = make(chan *Chameneos); + ref.done = make(chan int); + go ref.Serve(); + return ref; +} + +func (ref *Referee) Serve() { + for i := 0; i < *n; i++ { + c1 := <-ref.rendez; + c2 := <-ref.rendez; + c1.col, c2.col = complement(c1.col, c2.col), complement(c2.col, c1.col); + c1.rendez <- c2; + c2.rendez <- c1; + } + for i := 0; i < len(ref.cham); i++ { + c := <-ref.rendez; + c.rendez <- nil; + } + ref.done <- 1; +} + +func (ref *Referee) Add(ch *Chameneos) { + n := len(ref.cham); + ref.cham = ref.cham[0:n+1]; + ref.cham[n] = ch; +} + +type Chameneos struct { + index int; + col Color; + rendez chan *Chameneos; + count int; + same int; + ref *Referee; +} + +func (c *Chameneos) Init(index int, ref *Referee, col Color) *Chameneos { + c.index = index; + c.ref = ref; + c.col = col; + c.rendez = make(chan *Chameneos); + go c.Serve(); + return c; +} + +func (c *Chameneos) Serve() { + for { + c.ref.rendez <- c; + c1 := <- c.rendez; + if c1 == nil { + break + } + if c1.index == c.index { + c.same++ + } + c.count++; + } +} + +func play(ref *Referee, color []Color) { + cham := make([]Chameneos, len(color)); + for i, c := range color { + fmt.Printf("%s ", c); + ref.Add(cham[i].Init(i, ref, c)); + } + fmt.Printf("\n"); + <-ref.done; + total := 0; + for i, c := range cham { + total += c.count; + fmt.Printf("%d %s\n", c.count, say(c.same)); + } + fmt.Printf("%s\n\n", say(total)); +} + +var words = []string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"} + +func say(n int) string { + digits := fmt.Sprint(n); + s := ""; + for _, c := range digits { + s += " " + words[c-'0']; + } + return s; +} + +func main() { + flag.Parse(); + printColorTable(); + fmt.Print("\n"); + play(NewReferee(), []Color{blue, red, yellow}); + play(NewReferee(), []Color{blue, red, yellow, red, yellow, blue, red, yellow, red, blue}); +} |
