Skip to content

Instantly share code, notes, and snippets.

@morontt
Last active May 16, 2019 16:09
Show Gist options
  • Save morontt/160c05223ef754831fbaa0c2798e7048 to your computer and use it in GitHub Desktop.
Save morontt/160c05223ef754831fbaa0c2798e7048 to your computer and use it in GitHub Desktop.
Chicken problem
package main
// About chickens
// https://habr.com/ru/post/348066
import (
crand "crypto/rand"
"fmt"
"math"
"math/rand"
)
const count = 400
const iteration = 1000000
const (
_ = 1 << (8 * iota)
p1
p2
p3
p4
p5
)
type Chicken struct {
isPecked bool
Left *Chicken
Right *Chicken
}
type Ring [count]*Chicken
func (c *Chicken) Peck() {
var z = rand.Intn(256)
if z%2 == 0 {
c.Left.isPecked = true
} else {
c.Right.isPecked = true
}
}
func process(r *Ring) int {
var ring Ring
var cnt int
ring = *r
for i := range ring {
ring[i].isPecked = false
}
for i := range ring {
ring[i].Peck()
}
for i := range ring {
if !ring[i].isPecked {
cnt++
}
}
return cnt
}
func initRand() {
var seed int64
bytes := make([]byte, 6)
_, err := crand.Read(bytes)
if err != nil {
panic(err)
}
seed = int64(bytes[0])
seed += int64(bytes[1]) * p1
seed += int64(bytes[2]) * p2
seed += int64(bytes[3]) * p3
seed += int64(bytes[4]) * p4
seed += int64(bytes[5]) * p5
rand.Seed(seed)
}
func createRing() *Ring {
var ring Ring
var ch *Chicken
for i := 0; i < count; i++ {
ring[i] = new(Chicken)
}
for i := range ring {
ch = ring[i]
if i == 0 {
ch.Left = ring[count-1]
} else {
ch.Left = ring[i-1]
}
if i == (count - 1) {
ch.Right = ring[0]
} else {
ch.Right = ring[i+1]
}
}
return &ring
}
func main() {
var cnt, sum, sumsqr int
var avg, avgsqr float64
initRand()
ref := createRing()
for i := 0; i < iteration; i++ {
cnt = process(ref)
sum += cnt
sumsqr += cnt * cnt
}
avg = float64(sum) / iteration
avgsqr = float64(sumsqr) / iteration
variance := math.Sqrt((avgsqr - avg*avg) / (iteration - 1))
fmt.Printf("P: %.9f\nS: %.9f\n", avg/count, variance/count)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment