forked from extemporalgenome/sortutil
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathseq.go
More file actions
62 lines (56 loc) · 1.62 KB
/
seq.go
File metadata and controls
62 lines (56 loc) · 1.62 KB
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
// Copyright 2013 The Go 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
import (
"math/rand"
"sort"
)
// Reverse inverts the current order of the provided data.
func Reverse(data sort.Interface) {
n := data.Len()
for i := 0; i < n/2; i++ {
data.Swap(i, n-i-1)
}
}
// Rotate cycles data by d moves to the right.
// The d rightmost block of items will be shifted to the front.
// If d is negative, the shift will be leftward.
func Rotate(data sort.Interface, d int) {
k := data.Len()
d = (k + d) % k
Skew(data, 0, d, k-d)
}
// Skew slides a group of k consecutive elements from index i to index j.
// i and j respectively represent the source and destination indices of the
// group's minimum-indexed edge. If j > i, the group will slide toward larger
// indices, while if j < i, the group will slide toward smaller indices.
//
// i, j, and k should all be non-negative integers within the range of
// [0,n), where n == data.Len().
func Skew(data sort.Interface, i, j, k int) {
if k == 0 || i == j {
return
} else if j < i {
i, j, k = j, j+k, i-j
}
if j-i < k {
// if the block size is larger than the delta...
p := k / 2
q := k - p
Skew(data, i+p, j+p, q)
Skew(data, i, j, p)
} else if p := (j - i) % k; p != 0 {
// if the delta is not evenly divisible by the block size...
Skew(data, i, j-p, k)
Skew(data, j-p, j, k)
} else {
for ; i < j; i++ {
data.Swap(i, i+k)
}
}
}
// Shuffle sorts data randomly.
func Shuffle(data sort.Interface) {
sort.Sort(NewProxy(sort.IntSlice(rand.Perm(data.Len())), data))
}