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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
|
// Copyright 2014 The sortutil Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package sortutil provides utilities supplementing the standard 'sort' package.
//
// Changelog
//
// 2015-06-17: Added utils for math/big.{Int,Rat}.
package sortutil
import (
"math/big"
)
import "sort"
// BigIntSlice attaches the methods of sort.Interface to []*big.Int, sorting in increasing order.
type BigIntSlice []*big.Int
func (s BigIntSlice) Len() int { return len(s) }
func (s BigIntSlice) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
func (s BigIntSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s BigIntSlice) Sort() {
sort.Sort(s)
}
// SearchBigInts searches for x in a sorted slice of *big.Int and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchBigInts(a []*big.Int, x *big.Int) int {
return sort.Search(len(a), func(i int) bool { return a[i].Cmp(x) >= 0 })
}
// BigRatSlice attaches the methods of sort.Interface to []*big.Rat, sorting in increasing order.
type BigRatSlice []*big.Rat
func (s BigRatSlice) Len() int { return len(s) }
func (s BigRatSlice) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
func (s BigRatSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s BigRatSlice) Sort() {
sort.Sort(s)
}
// SearchBigRats searches for x in a sorted slice of *big.Int and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchBigRats(a []*big.Rat, x *big.Rat) int {
return sort.Search(len(a), func(i int) bool { return a[i].Cmp(x) >= 0 })
}
// ByteSlice attaches the methods of sort.Interface to []byte, sorting in increasing order.
type ByteSlice []byte
func (s ByteSlice) Len() int { return len(s) }
func (s ByteSlice) Less(i, j int) bool { return s[i] < s[j] }
func (s ByteSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s ByteSlice) Sort() {
sort.Sort(s)
}
// SearchBytes searches for x in a sorted slice of bytes and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchBytes(a []byte, x byte) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Float32Slice attaches the methods of sort.Interface to []float32, sorting in increasing order.
type Float32Slice []float32
func (s Float32Slice) Len() int { return len(s) }
func (s Float32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Float32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Float32Slice) Sort() {
sort.Sort(s)
}
// SearchFloat32s searches for x in a sorted slice of float32 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchFloat32s(a []float32, x float32) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Int8Slice attaches the methods of sort.Interface to []int8, sorting in increasing order.
type Int8Slice []int8
func (s Int8Slice) Len() int { return len(s) }
func (s Int8Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Int8Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Int8Slice) Sort() {
sort.Sort(s)
}
// SearchInt8s searches for x in a sorted slice of int8 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchInt8s(a []int8, x int8) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Int16Slice attaches the methods of sort.Interface to []int16, sorting in increasing order.
type Int16Slice []int16
func (s Int16Slice) Len() int { return len(s) }
func (s Int16Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Int16Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Int16Slice) Sort() {
sort.Sort(s)
}
// SearchInt16s searches for x in a sorted slice of int16 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchInt16s(a []int16, x int16) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Int32Slice attaches the methods of sort.Interface to []int32, sorting in increasing order.
type Int32Slice []int32
func (s Int32Slice) Len() int { return len(s) }
func (s Int32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Int32Slice) Sort() {
sort.Sort(s)
}
// SearchInt32s searches for x in a sorted slice of int32 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchInt32s(a []int32, x int32) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Int64Slice attaches the methods of sort.Interface to []int64, sorting in increasing order.
type Int64Slice []int64
func (s Int64Slice) Len() int { return len(s) }
func (s Int64Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Int64Slice) Sort() {
sort.Sort(s)
}
// SearchInt64s searches for x in a sorted slice of int64 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchInt64s(a []int64, x int64) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// UintSlice attaches the methods of sort.Interface to []uint, sorting in increasing order.
type UintSlice []uint
func (s UintSlice) Len() int { return len(s) }
func (s UintSlice) Less(i, j int) bool { return s[i] < s[j] }
func (s UintSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s UintSlice) Sort() {
sort.Sort(s)
}
// SearchUints searches for x in a sorted slice of uints and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchUints(a []uint, x uint) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Uint16Slice attaches the methods of sort.Interface to []uint16, sorting in increasing order.
type Uint16Slice []uint16
func (s Uint16Slice) Len() int { return len(s) }
func (s Uint16Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Uint16Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Uint16Slice) Sort() {
sort.Sort(s)
}
// SearchUint16s searches for x in a sorted slice of uint16 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchUint16s(a []uint16, x uint16) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Uint32Slice attaches the methods of sort.Interface to []uint32, sorting in increasing order.
type Uint32Slice []uint32
func (s Uint32Slice) Len() int { return len(s) }
func (s Uint32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Uint32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Uint32Slice) Sort() {
sort.Sort(s)
}
// SearchUint32s searches for x in a sorted slice of uint32 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchUint32s(a []uint32, x uint32) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Uint64Slice attaches the methods of sort.Interface to []uint64, sorting in increasing order.
type Uint64Slice []uint64
func (s Uint64Slice) Len() int { return len(s) }
func (s Uint64Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Uint64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s Uint64Slice) Sort() {
sort.Sort(s)
}
// SearchUint64s searches for x in a sorted slice of uint64 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchUint64s(a []uint64, x uint64) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// RuneSlice attaches the methods of sort.Interface to []rune, sorting in increasing order.
type RuneSlice []rune
func (s RuneSlice) Len() int { return len(s) }
func (s RuneSlice) Less(i, j int) bool { return s[i] < s[j] }
func (s RuneSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// Sort is a convenience method.
func (s RuneSlice) Sort() {
sort.Sort(s)
}
// SearchRunes searches for x in a sorted slice of uint64 and returns the index
// as specified by sort.Search. The slice must be sorted in ascending order.
func SearchRunes(a []rune, x rune) int {
return sort.Search(len(a), func(i int) bool { return a[i] >= x })
}
// Dedupe returns n, the number of distinct elements in data. The resulting
// elements are sorted in elements [0, n) or data[:n] for a slice.
func Dedupe(data sort.Interface) (n int) {
if n = data.Len(); n < 2 {
return n
}
sort.Sort(data)
a, b := 0, 1
for b < n {
if data.Less(a, b) {
a++
if a != b {
data.Swap(a, b)
}
}
b++
}
return a + 1
}
|