Skip to content

Instantly share code, notes, and snippets.

@darkfeline
Last active September 1, 2024 09:08
Show Gist options
  • Save darkfeline/241fd0e31641b1e70cb879182d832fc0 to your computer and use it in GitHub Desktop.
Save darkfeline/241fd0e31641b1e70cb879182d832fc0 to your computer and use it in GitHub Desktop.
Capturing Radiance simulation
package main
import (
"fmt"
rand "math/rand/v2"
"sync"
)
type count struct {
wins float64
grid [8]float64
}
func (c *count) add(r result) {
if r.win {
c.wins += 1
c.grid[r.losses] += 1
}
}
func (c *count) combine(c2 count) {
c.wins = c.wins + c2.wins
for i := range c.grid {
c.grid[i] = c.grid[i] + c2.grid[i]
}
}
type result struct {
win bool
losses int
}
type roller struct {
r *rand.Rand
losses int
}
func (r *roller) roll() result {
if r.r.Float64() < 0.5 {
r.losses = 0
return result{win: true}
}
if r.r.Float64() < (float64(max(r.losses-0, 0)) / 7) {
l := r.losses
r.losses = 0
return result{win: true, losses: l}
}
r.losses += 1
return result{win: false}
}
func newRoller() *roller {
return &roller{
r: rand.New(rand.NewPCG(rand.Uint64(), rand.Uint64())),
}
}
func main() {
const total = 800_000_000
const threads = 4
var wg sync.WaitGroup
counts := make(chan count, threads)
for i := 0; i < threads; i++ {
wg.Add(1)
go func() {
defer wg.Done()
r := newRoller()
c := count{}
for i := 0; i < total; i++ {
c.add(r.roll())
}
counts <- c
}()
}
go func() {
wg.Wait()
close(counts)
}()
c := count{}
for c2 := range counts {
c.combine(c2)
}
const grand = total * threads
fmt.Printf("%f\n", c.wins/grand)
for i, v := range c.grid {
fmt.Printf("%d losses: %f\n", i, v/grand)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment