Skip to content

Instantly share code, notes, and snippets.

@todoa2c
Last active December 20, 2015 09:40
Show Gist options
  • Save todoa2c/6109960 to your computer and use it in GitHub Desktop.
Save todoa2c/6109960 to your computer and use it in GitHub Desktop.
Goで書くサンタクロース問題 http://karetta.jp/article/blog/oneline/030756
// サンタクロース問題
// http://karetta.jp/article/blog/oneline/030756
package main
import (
"fmt"
"math/rand"
"time"
)
type visitor interface {
act(home chan visitor)
}
type elf struct {
id int
r *rand.Rand
}
type reindeer struct {
id int
r *rand.Rand
}
func (d elf) act(home chan visitor) {
time.Sleep(time.Duration(d.r.Int63n(10)) * time.Second)
fmt.Printf("Elf #%d came to Santa's home\n", d.id)
home <- d
}
func (c reindeer) act(home chan visitor) {
time.Sleep(time.Duration(c.r.Int63n(8)) * time.Second)
fmt.Printf("Reindeer #%d came to Santa's home\n", c.id)
home <- c
}
func startReindeers(home chan visitor) {
for i := 0; i < 9; i++ {
c := reindeer{i, rand.New(rand.NewSource(time.Now().UnixNano() + int64(i)))}
go c.act(home)
}
}
func startElves(home chan visitor) {
for i := 0; i < 10; i++ {
d := elf{i, rand.New(rand.NewSource(time.Now().UnixNano() + int64(i)))}
go d.act(home)
}
}
func release(all []visitor, home chan visitor) []visitor {
for _, member := range all {
go member.act(home)
}
return queue()
}
func queue() []visitor {
return make([]visitor, 0, 10)
}
func main() {
home := make(chan visitor)
startReindeers(home)
startElves(home)
reindeers := queue()
elves := queue()
stop := make(chan bool)
go func() {
time.Sleep(30 * time.Second)
fmt.Println("STOP CALLED")
stop <- true
}()
for {
select {
case <-stop:
fmt.Println("Finished.")
return
case visitor := <-home:
_, ok := visitor.(reindeer)
if ok {
reindeers = append(reindeers, visitor)
} else {
elves = append(elves, visitor)
}
if len(reindeers) == 9 {
fmt.Println("*** Santa went to deliver presents: ", reindeers)
time.Sleep(time.Duration(10) * time.Second)
reindeers = release(reindeers, home)
fmt.Println("*** Delivery finished")
}
if len(elves) == 3 {
fmt.Println("### Santa is meeting up with elves: ", elves)
time.Sleep(time.Duration(5) * time.Second)
elves = release(elves, home)
fmt.Println("### Meeting finished")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment