-
Notifications
You must be signed in to change notification settings - Fork 0
/
placings.go
88 lines (73 loc) · 1.63 KB
/
placings.go
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
package brdgme
import (
"sort"
"strconv"
"strings"
)
type placOrd int8
const (
placOrdLess placOrd = -1
placOrdEqual placOrd = 0
placOrdGreater placOrd = 1
)
func cmpMetrics(a, b []int) placOrd {
aLen, bLen := len(a), len(b)
if aLen == 0 && bLen == 0 {
return placOrdEqual
}
if aLen == 0 {
return placOrdLess
}
if bLen == 0 {
return placOrdGreater
}
if a[0] < b[0] {
return placOrdLess
}
if a[0] > b[0] {
return placOrdGreater
}
return cmpMetrics(a[1:], b[1:])
}
type placMetrics [][]int
func (s placMetrics) Len() int { return len(s) }
func (s placMetrics) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s placMetrics) Less(i, j int) bool {
return cmpMetrics(s[i], s[j]) == placOrdLess
}
var _ sort.Interface = placMetrics{}
func placMetricKey(metric []int) string {
metricStrs := make([]string, len(metric))
for k, m := range metric {
metricStrs[k] = strconv.Itoa(m)
}
return strings.Join(metricStrs, ",")
}
func GenPlacings(metrics [][]int) []int {
grouped := map[string][]int{}
byMetricKey := map[string][]int{}
for p, m := range metrics {
mKey := placMetricKey(m)
grouped[mKey] = append(grouped[mKey], p)
byMetricKey[mKey] = m
}
uniqueMetrics := [][]int{}
for _, m := range byMetricKey {
uniqueMetrics = append(uniqueMetrics, m)
}
sort.Sort(sort.Reverse(placMetrics(uniqueMetrics)))
placingMap := map[int]int{}
curPlace := 1
for _, m := range uniqueMetrics {
mKey := placMetricKey(m)
for _, p := range grouped[mKey] {
placingMap[p] = curPlace
}
curPlace++
}
placings := make([]int, len(metrics))
for p := range metrics {
placings[p] = placingMap[p]
}
return placings
}