Created
February 25, 2015 11:46
-
-
Save macu/2e778f45d428cc6a462d to your computer and use it in GitHub Desktop.
Sort method to find best order
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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