Last active
May 16, 2019 16:09
-
-
Save morontt/160c05223ef754831fbaa0c2798e7048 to your computer and use it in GitHub Desktop.
Chicken problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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