RosettaCodeData/Task/Permutation-test/Go/permutation-test.go

73 lines
1.8 KiB
Go

package main
import "fmt"
var tr = []int{85, 88, 75, 66, 25, 29, 83, 39, 97}
var ct = []int{68, 41, 10, 49, 16, 65, 32, 92, 28, 98}
func main() {
// collect all results in a single list
all := make([]int, len(tr)+len(ct))
copy(all, tr)
copy(all[len(tr):], ct)
// compute sum of all data, useful as intermediate result
var sumAll int
for _, r := range all {
sumAll += r
}
// closure for computing scaled difference.
// compute results scaled by len(tr)*len(ct).
// this allows all math to be done in integers.
sd := func(trc []int) int {
var sumTr int
for _, x := range trc {
sumTr += all[x]
}
return sumTr*len(ct) - (sumAll-sumTr)*len(tr)
}
// compute observed difference, as an intermediate result
a := make([]int, len(tr))
for i, _ := range a {
a[i] = i
}
sdObs := sd(a)
// iterate over all combinations. for each, compute (scaled)
// difference and tally whether leq or gt observed difference.
var nLe, nGt int
comb(len(all), len(tr), func(c []int) {
if sd(c) > sdObs {
nGt++
} else {
nLe++
}
})
// print results as percentage
pc := 100 / float64(nLe+nGt)
fmt.Printf("differences <= observed: %f%%\n", float64(nLe)*pc)
fmt.Printf("differences > observed: %f%%\n", float64(nGt)*pc)
}
// combination generator, copied from combination task
func comb(n, m int, emit func([]int)) {
s := make([]int, m)
last := m - 1
var rc func(int, int)
rc = func(i, next int) {
for j := next; j < n; j++ {
s[i] = j
if i == last {
emit(s)
} else {
rc(i+1, j+1)
}
}
return
}
rc(0, 0)
}