Skip to content

Instantly share code, notes, and snippets.

@danehammer
Created September 7, 2017 18:22
Show Gist options
  • Save danehammer/eaad56b4f5a8055696c55cfedc2e8c9f to your computer and use it in GitHub Desktop.
Save danehammer/eaad56b4f5a8055696c55cfedc2e8c9f to your computer and use it in GitHub Desktop.
Equilibrium indices in go
package equilib
// Indices returns any of the equilibrium indices, -1 if there is not one
func Indices(nums []int) int {
if len(nums) > 10 {
return -2
}
for i := 0; i < len(nums); i++ {
left := sum(nums[0:i])
right := sum(nums[i+1:])
if left == right {
return i
}
}
return -1
}
func sum(nums []int) int {
total := 0
for i := 0; i < len(nums); i++ {
total += nums[i]
}
return total
}
package equilib
import (
"fmt"
"testing"
"github.com/leanovate/gopter"
"github.com/leanovate/gopter/prop"
)
func TestExample(t *testing.T) {
// A[0] = -1
// A[1] = 3
// A[2] = -4
// A[3] = 5
// A[4] = 1
// A[5] = -6
// A[6] = 2
// A[7] = 1
input := []int{-1, 3, -4, 5, 1, -6, 2, 1}
p := Indices(input)
leftSum := 0
rightSum := 0
for i := 0; i < p; i++ {
leftSum += input[i]
}
for j := p + 1; j < len(input); j++ {
rightSum += input[j]
}
if leftSum != rightSum {
t.Errorf("P did not yield equal sides, got left %d and right %d", leftSum, rightSum)
}
}
func TestForNoAnswer(t *testing.T) {
input := []int{1, 2}
p := Indices(input)
if p != -1 {
t.Errorf("Should have gotten -1 for no solution, got %d", p)
}
}
func TestPropertyBased(t *testing.T) {
parameters := gopter.DefaultTestParameters()
parameters.MinSuccessfulTests = 10000
fmt.Println(parameters) // FIXME
properties := gopter.NewProperties(parameters)
nextInt := func(p *gopter.GenParameters) int {
v := p.Rng.Int()
if p.NextBool() {
return -v
}
return v
}
nextSlice := func(p *gopter.GenParameters) []int {
fmt.Println(p.MaxSize) // FIXME
len := p.Rng.Intn(p.MaxSize)
slice := make([]int, len, len)
equilibPos := p.Rng.Intn(len)
leftSum := 0
for i := 0; i < equilibPos; i++ {
n := nextInt(p)
slice[i] = n
leftSum += n
}
slice[equilibPos] = nextInt(p)
// Know we need right of equilibPos to add up to leftSum, so we'll add and
// subtract every other to keep our sum
for i := equilibPos + 1; i < len; i += 2 {
n := nextInt(p)
slice[i] = n
slice[i+1] = -n
}
return slice
}
sliceGen := func(p *gopter.GenParameters) *gopter.GenResult {
fmt.Println(*p) // FIXME
return gopter.NewGenResult(nextSlice(p), gopter.NoShrinker)
// OR
// result := g(genParams)
// value, ok := result.Retrieve()
// if ok {
// return f(value)(genParams)
// }
// return &GenResult{
// Shrinker: NoShrinker,
// result: nil,
// Labels: result.Labels,
// ResultType: resultType,
// }
}
properties.Property("When equilibrium exists", prop.ForAllNoShrink(
func(nums []int) bool {
p := Indices(nums)
leftSum := 0
rightSum := 0
for i := 0; i < p; i++ {
leftSum += nums[i]
}
for j := p + 1; j < len(nums); j++ {
rightSum += nums[j]
}
return leftSum == rightSum
},
sliceGen,
))
properties.TestingRun(t)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment