Skip to content

Instantly share code, notes, and snippets.

@macu
Created February 25, 2015 11:46
Show Gist options
  • Select an option

  • Save macu/2e778f45d428cc6a462d to your computer and use it in GitHub Desktop.

Select an option

Save macu/2e778f45d428cc6a462d to your computer and use it in GitHub Desktop.
Sort method to find best order
package main
import "fmt"
type element struct {
count int
}
var samples = [][]int{
{1, 2, 3, 4, 5, 6, 7, 8, 9},
}
func main() {
// extract all elements.
var elements = make(map[int]*element)
for _, ints := range samples {
for _, i := range ints {
// record the presence of the element.
if e := elements[i]; e != nil {
e.count++
} else {
elements[i] = &element{count: 1}
}
}
}
// build new array.
// insert i where it has strongest presence in the samples.
var ordered = make([]int, 0)
for a, e := range elements {
// only accept elements with adequate presence in the samples.
const minPresence = .8
if float64(e.count)/float64(len(samples)) < minPresence {
continue
}
// find the best position for the number.
var mostSignificantIndex = 0
var mostSignificantSignificance = 0
for i, b := range ordered {
// determine the positional relationship of a to b.
// - does a always come before b? then it must be inserted presently,
// if not even earlier in the array.
// - if a appears before b less than 50% of the time then put a after b.
// - the best position will satisfy the greatest number of relationships.
// - relationships that hold for 100% of samples must all be respected.
// - this algorithm considers only the relative ordering in samples,
// and does not directly determine the proximity of two numbers.
var appearedBefore = 0
var appearedAfter = 0
var appearedTogether = 0
for _, s := range samples {
if ai := find(a, s); ai != nil {
if bi := find(b, s); bi != nil {
if *ai <= *bi {
appearedBefore++
} else {
appearedAfter++
}
appearedTogether++
}
}
}
// ...
}
// insert number at most significant index in array.
ordered = insert(a, mostSignificantIndex, ordered)
}
// print the predicted order.
fmt.Println("Output:")
for _, a := range ordered {
fmt.Println(a)
}
}
// returns a new slice with the given given number
// inserted at the specified position.
func insert(a int, at int, ints []int) []int {
ints = append(ints, 0)
copy(ints[at+1:], ints[at:])
ints[at] = a
return ints
}
// returns the index of the given number in the array of ints.
// returns nil if the number is not found in the array.
func find(a int, ints []int) *int {
for i := 0; i < len(ints); i++ {
if ints[i] == a {
return &i
}
}
return nil
}
// returns whether a occurs before b in the array of ints.
// returns nil if either number is not found in the array.
func before(a, b int, ints []int) *bool {
var ai = find(a, ints)
if ai != nil {
var bi = find(b, ints)
if bi != nil {
var bef = *ai < *bi
return &bef
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment