Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 124 lines (104 sloc) 2.224 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
package main

import (
"log"
"math/rand"
)

const (
BOARDSIZE = 5
MIDDLE = 2
NUMBERS = 75
NUMBERS_PER_COLUMN = NUMBERS / BOARDSIZE
)

type Board struct {
// counts of how many squares are filled in
// each row/col/diagonal
rows [BOARDSIZE]int
cols [BOARDSIZE]int
diagonals [2]int
}

type PlaceList []*int

type Game struct {
boards []*Board

// For each number that can be called out,
// a list of pointers to counters for the rows/cols/diagonals
// that number is used in (across all the boards)
places [NUMBERS]PlaceList
}

func (g *Game) Init(boards int) {
for j := 0; j < boards; j++ {
b := new(Board)
b.Init(g)
g.boards = append(g.boards, b)
}
}

func main() {
log.SetFlags(0) // quieter logging

average(500, 100000)
}

func average(boards, iterations int) {
var g Game

g.Init(boards)
log.Printf("%d boards, %d iterations, %.2f average",
boards, iterations, g.findAverage(iterations))

}

func (g *Game) addPointer(n int, p *int) {
g.places[n] = append(g.places[n], p)
}

func (g *Game) findAverage(iterations int) float64 {
var length = 0
for j := 0; j < iterations; j++ {
length += g.gameLength()
g.reset()
}
return float64(length) / float64(iterations)
}

func (g *Game) reset() {
for _, b := range g.boards {
b.reset()
}
}

func (b *Board) reset() {
b.diagonals[0] = 1
b.diagonals[1] = 1
for j := 0; j < BOARDSIZE; j++ {
var val = 0
if j == MIDDLE {
val = 1
}
b.cols[j] = val
b.rows[j] = val
}
}

func (g *Game) gameLength() int {
for pos, n := range rand.Perm(NUMBERS) {
for _, p := range g.places[n] {
*p += 1
if *p == BOARDSIZE {
// log.Print("gameLenth:", pos)
return pos
}
}
}
panic("cannot get here")
return 0
}

func (b *Board) Init(g *Game) {
b.reset()

for col := 0; col < BOARDSIZE; col++ {
perms := rand.Perm(NUMBERS_PER_COLUMN)[:BOARDSIZE]
for row, n := range perms {
if row == MIDDLE && col == MIDDLE {
continue
}
n += col * NUMBERS_PER_COLUMN
g.addPointer(n, &b.cols[col])
g.addPointer(n, &b.rows[row])
if row == col {
g.addPointer(n, &b.diagonals[0])
}
if row+col == BOARDSIZE-1 {
g.addPointer(n, &b.diagonals[1])
}
}
}
}
Something went wrong with that request. Please try again.