Copy dependencies into vendor dir, using dep

This commit is contained in:
Bryan Boreham committed 2018-04-27 14:34:48 +01:00
1 parent 549ccff5eb
commit b534ea60f5
2857 files changed
+945317

No files matched your search

+309
View File
@@ -0,0 +1,309 @@
# bit
--
import "github.com/andybalholm/go-bit"
Package bit provides a bitset implementation and utility bit functions for
uint64 words.
## Usage
```go
const (
MaxInt = 1<<(BitsPerWord-1) - 1 // either 1<<31 - 1 or 1<<63 - 1
MinInt = -MaxInt - 1 // either -1 << 31 or -1 << 63
MaxUint = 1<<BitsPerWord - 1 // either 1<<32 - 1 or 1<<64 - 1
)
```
Implementation-specific integer limit values.
```go
const BitsPerWord = bitsPerWord // either 32 or 64
```
Implementation-specific size of int and uint in bits.
#### func Count
```go
func Count(w uint64) int
```
Count returns the number of nonzero bits in w.
#### func MaxPos
```go
func MaxPos(w uint64) int
```
MaxPos returns the position of the maximum nonzero bit in w, w ≠ 0. It panics
for w = 0.
#### func MinPos
```go
func MinPos(w uint64) int
```
MinPos returns the position of the minimum nonzero bit in w, w ≠ 0. It panics
for w = 0.
#### type Set
```go
type Set struct {
}
```
Set represents a mutable set of non-negative integers. The zero value of Set is
an empty set ready to use. A set occupies approximately n bits, where n is the
maximum value that has been stored in the set.
#### func New
```go
func New(n ...int) (S *Set)
```
New creates a new set S with the given elements.
#### func (*Set) Add
```go
func (S *Set) Add(n int) *Set
```
Add adds n to S, setting S to S ∪ {n}, and returns the updated set.
#### func (*Set) AddRange
```go
func (S *Set) AddRange(m, n int) *Set
```
AddRange adds all integers between m and n-1, m ≤ n, setting S to S ∪ {m..n-1},
and returns the updated set.
#### func (*Set) And
```go
func (A *Set) And(B *Set) (S *Set)
```
And creates a new intersection S = A ∩ B that consists of all elements that
belong to both A and B.
#### func (*Set) AndNot
```go
func (A *Set) AndNot(B *Set) (S *Set)
```
AndNot creates a new set difference S = A ∖ B that consists of all elements that
belong to A, but not to B.
#### func (*Set) Clear
```go
func (S *Set) Clear() *Set
```
Clear removes all elements and returns the updated empty set.
#### func (*Set) Contains
```go
func (S *Set) Contains(n int) bool
```
Contains returns true if n, n ≥ 0, is an element of S.
#### func (*Set) Do
```go
func (S *Set) Do(f func(n int))
```
Do calls function f for each element n ∊ S in numerical order. It is safe for f
to add or remove elements e, e ≤ n, from S. The behavior of Do is undefined if f
changes the set in any other way.
#### func (*Set) Equals
```go
func (A *Set) Equals(B *Set) bool
```
Equals returns true if A and B contain the same elements.
#### func (*Set) Flip
```go
func (S *Set) Flip(n int) *Set
```
Flip removes n from S if it is present, otherwise it adds n, setting S to S ∆
{n}, and returns the updated set.
#### func (*Set) FlipRange
```go
func (S *Set) FlipRange(m, n int) *Set
```
FlipRange flips all elements in the range m..n-1, m ≤ n, setting S to S ∆
{m..n-1}, and returns the updated set.
#### func (*Set) Intersects
```go
func (A *Set) Intersects(B *Set) bool
```
Intersects returns true if A and B overlap, i.e. A ∩ B ≠ ∅.
#### func (*Set) IsEmpty
```go
func (S *Set) IsEmpty() bool
```
IsEmpty returns true if S = ∅.
#### func (*Set) Max
```go
func (S *Set) Max() int
```
Max returns the maximum element of the set. It panics if S is empty.
#### func (*Set) Min
```go
func (S *Set) Min() int
```
Min returns the minimum element of the set. It panics if S is empty.
#### func (*Set) Next
```go
func (S *Set) Next(m int) (n int, found bool)
```
Next returns (n, true), where n is the smallest element of S such that m < n, or
(0, false) if no such element exists.
#### func (*Set) Or
```go
func (A *Set) Or(B *Set) (S *Set)
```
Or creates a new union S = A ∪ B that contains all elements that belong to
either A or B.
#### func (*Set) Previous
```go
func (S *Set) Previous(m int) (n int, found bool)
```
Previous returns (n, true), where n is the largest element of S such that n < m,
or (0, false) if no such element exists.
#### func (*Set) Remove
```go
func (S *Set) Remove(n int) *Set
```
Remove removes n from S, setting S to S ∖ {n}, and returns the updated set.
#### func (*Set) RemoveMax
```go
func (S *Set) RemoveMax() (max int)
```
RemoveMax removes the maximum element from S, setting S to S ∖ {max}, and
returns max. It panics if S is empty.
#### func (*Set) RemoveMin
```go
func (S *Set) RemoveMin() (min int)
```
RemoveMin removes the minimum element from S, setting S to S ∖ {min}, and
returns min. It panics if S is empty.
#### func (*Set) RemoveRange
```go
func (S *Set) RemoveRange(m, n int) *Set
```
RemoveRange removes all integers between m and n-1, m ≤ n, setting S to S ∖
{m..n-1}, and returns the updated set.
#### func (*Set) Set
```go
func (S *Set) Set(A *Set) *Set
```
Set sets S to A and returns S.
#### func (*Set) SetAnd
```go
func (S *Set) SetAnd(A, B *Set) *Set
```
SetAnd sets S to the intersection A ∩ B and returns S.
#### func (*Set) SetAndNot
```go
func (S *Set) SetAndNot(A, B *Set) *Set
```
SetAndNot sets S to the set difference A ∖ B and returns S.
#### func (*Set) SetOr
```go
func (S *Set) SetOr(A, B *Set) *Set
```
SetOr sets S to the union A ∪ B and returns S.
#### func (*Set) SetWord
```go
func (S *Set) SetWord(i int, w uint64) *Set
```
SetWord interprets w as a bitset with numbers in the range 64i to 64i + 63,
where 0 ≤ i ≤ ⌊MaxInt/64⌋, overwrites this range in S with w, and returns S.
#### func (*Set) SetXor
```go
func (S *Set) SetXor(A, B *Set) *Set
```
SetXor sets S to the symmetric difference A ∆ B = (A ∪ B) ∖ (A ∩ B) and returns
S.
#### func (*Set) Size
```go
func (S *Set) Size() int
```
Size returns |S|, the number of elements in S. This method scans the set. To
check if a set is empty, consider using the more efficient IsEmpty.
#### func (*Set) String
```go
func (S *Set) String() string
```
String returns a string representation of S. The elements are listed in
ascending order, enclosed by braces, and separated by ", ". Runs of at least
three elements a, a+1, ..., b are given as "a..b".
For example, the set {1, 2, 6, 5, 3} is represented as "{1..3, 5, 6}".
#### func (*Set) SubsetOf
```go
func (A *Set) SubsetOf(B *Set) bool
```
SubsetOf returns true if A ⊆ B.
#### func (*Set) Word
```go
func (S *Set) Word(i int) (w uint64)
```
Word returns the range 64i to 64i + 63 of S as a bitset represented by w.
#### func (*Set) Xor
```go
func (A *Set) Xor(B *Set) (S *Set)
```
Xor creates a new symmetric difference S = A ∆ B = (A ∪ B) ∖ (A ∩ B) that
consists of all elements that belong to either A or B, but not to both.
+100
View File
@@ -0,0 +1,100 @@
// Copyright 2012 Stefan Nilsson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bit
// Note the use of << to create an untyped constant.
const bitsPerWord = 32 << uint(^uint(0)>>63)
// Implementation-specific size of int and uint in bits.
const BitsPerWord = bitsPerWord // either 32 or 64
// Implementation-specific integer limit values.
const (
MaxInt = 1<<(BitsPerWord-1) - 1 // either 1<<31 - 1 or 1<<63 - 1
MinInt = -MaxInt - 1 // either -1 << 31 or -1 << 63
MaxUint = 1<<BitsPerWord - 1 // either 1<<32 - 1 or 1<<64 - 1
)
// MinPos returns the position of the minimum nonzero bit in w, w ≠ 0.
// It panics for w = 0.
func MinPos(w uint64) int {
// “Using de Bruijn Sequences to Index a 1 in a Computer Word”,
// Leiserson, Prokop, and Randall, MIT, 1998.
if w == 0 {
panic("bit: MinPos(0) undefined")
}
// w & -w clears all bits except the one at minimum position p.
// Hence, the multiplication below is equivalent to b26<<p.
// A table lookup translates the 64 possible outcomes into
// the exptected answer.
return bitPos[((w&-w)*b26)>>58]
}
// A sequence, starting with 6 zeros, that contains all possible
// 6-bit patterns as subseqences, a.k.a. De Bruijn B(2, 6).
const b26 uint64 = 0x022fdd63cc95386d
var bitPos [64]int
func init() {
for p := uint(0); p < 64; p++ {
bitPos[b26<<p>>58] = int(p)
}
}
// MaxPos returns the position of the maximum nonzero bit in w, w ≠ 0.
// It panics for w = 0.
func MaxPos(w uint64) int {
if w == 0 {
panic("bit: MaxPos(0) undefined")
}
// Fill word with ones on the right, e.g. 0x0000f308 -> 0x0000ffff.
w |= w >> 1
w |= w >> 2
w |= w >> 4
w |= w >> 8
w |= w >> 16
w |= w >> 32
return Count(w) - 1
}
// Count returns the number of nonzero bits in w.
func Count(w uint64) int {
// “Software Optimization Guide for AMD64 Processors”, Section 8.6.
const maxw = 1<<64 - 1
const bpw = 64
// Compute the count for each 2-bit group.
// Example using 16-bit word w = 00,01,10,11,00,01,10,11
// w - (w>>1) & 01,01,01,01,01,01,01,01 = 00,01,01,10,00,01,01,10
w -= (w >> 1) & (maxw / 3)
// Add the count of adjacent 2-bit groups and store in 4-bit groups:
// w & 0011,0011,0011,0011 + w>>2 & 0011,0011,0011,0011 = 0001,0011,0001,0011
w = w&(maxw/15*3) + (w>>2)&(maxw/15*3)
// Add the count of adjacent 4-bit groups and store in 8-bit groups:
// (w + w>>4) & 00001111,00001111 = 00000100,00000100
w += w >> 4
w &= maxw / 255 * 15
// Add all 8-bit counts with a multiplication and a shift:
// (w * 00000001,00000001) >> 8 = 00001000
w *= maxw / 255
w >>= (bpw/8 - 1) * 8
return int(w)
}
+890
View File
@@ -0,0 +1,890 @@
// Copyright 2012 Stefan Nilsson
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package bit provides a bitset implementation and utility bit functions for uint64 words.
package bit
import (
"bytes"
"strconv"
)
const (
bpw = 64 // bits per word
maxw = 1<<bpw - 1 // maximum value for a word
shift = 6
mask = 0x3f
)
// Set represents a mutable set of non-negative integers.
// The zero value of Set is an empty set ready to use.
// A set occupies approximately n bits, where n is the maximum
// value that has been stored in the set.
type Set struct {
// Invariants:
// • data[n>>shift] & (1<<(n&mask)) == 1 iff n belongs to set,
// • data[i] == 0 for all i such that len(data) ≤ i < cap(data),
// • len(data) == 0 if set is empty,
// • data[len(data)-1] != 0 if set is nonempty,
// • min is the minimum element of a nonempty set, 0 otherwise.
data []uint64
min int
}
// New creates a new set S with the given elements.
func New(n ...int) (S *Set) {
if len(n) == 0 {
return new(Set)
}
min, max := n[0], n[0]
for _, e := range n {
switch {
case e > max:
max = e
case e < min:
min = e
}
}
S = &Set{
data: make([]uint64, max>>shift+1),
min: min,
}
for _, e := range n {
S.data[e>>shift] |= 1 << uint(e&mask)
}
return
}
// Add adds n to S, setting S to S ∪ {n}, and returns the updated set.
func (S *Set) Add(n int) *Set {
if n < 0 {
panic("Set: Add(" + strconv.Itoa(n) + ") index out of range")
}
if len(S.data) == 0 || n < S.min {
S.min = n
}
i := n >> shift
if i >= len(S.data) {
S.resize(i + 1)
}
S.data[i] |= 1 << uint(n&mask)
return S
}
// AddRange adds all integers between m and n-1, m ≤ n,
// setting S to S ∪ {m..n-1}, and returns the updated set.
func (S *Set) AddRange(m, n int) *Set {
if m == n && m >= 0 {
return S
}
if m > n || m < 0 {
panic("Set: AddRange(" + strconv.Itoa(m) + ", " + strconv.Itoa(n) + ") bounds out of range")
}
if len(S.data) == 0 || m < S.min {
S.min = m
}
n--
low, high := m>>shift, n>>shift
if high >= len(S.data) {
S.resize(high + 1)
}
d := S.data
if low == high { // Range fits in one word.
d[low] |= bitMask(m&mask, n&mask)
} else { // Range spans at least two words.
d[low] |= bitMask(m&mask, bpw-1)
for i := low + 1; i < high; i++ {
d[i] = maxw
}
d[high] |= bitMask(0, n&mask)
}
return S
}
// Remove removes n from S, setting S to S ∖ {n}, and returns the updated set.
func (S *Set) Remove(n int) *Set {
if n < 0 {
panic("Set: Remove(" + strconv.Itoa(n) + ") index out of range")
}
if n < S.min {
return S
}
i := n >> shift
if i >= len(S.data) {
return S
}
S.data[i] &^= 1 << uint(n&mask)
S.trim()
if n == S.min {
S.min = findMinFrom(S.min, S.data)
}
return S
}
// RemoveMin removes the minimum element from S, setting S to S ∖ {min},
// and returns min. It panics if S is empty.
func (S *Set) RemoveMin() (min int) {
if len(S.data) == 0 {
panic("Set: RemoveMin not defined for empty set")
}
min = S.min
i := min >> shift
d := S.data
d[i] &^= 1 << uint(min&mask)
if d[i] != 0 || i+1 < len(d) { // There are more elements left.
S.min = findMinFrom(min, d)
} else {
S.Clear() // The array contains only zeroes.
}
return
}
// RemoveMax removes the maximum element from S, setting S to S ∖ {max},
// and returns max. It panics if S is empty.
func (S *Set) RemoveMax() (max int) {
if len(S.data) == 0 {
panic("Set: RemoveMax not defined for empty set")
}
d := S.data
i := len(d) - 1
w := d[i]
max = i<<shift + MaxPos(w)
d[i] &^= 1 << uint(max&mask)
S.trim()
return
}
// Min returns the minimum element of the set. It panics if S is empty.
func (S *Set) Min() int {
if len(S.data) == 0 {
panic("Set: Min not defined for empty set")
}
return S.min
}
// Max returns the maximum element of the set. It panics if S is empty.
func (S *Set) Max() int {
if len(S.data) == 0 {
panic("Set: Max not defined for empty set")
}
d := S.data
i := len(d) - 1
w := d[i]
return i<<shift + MaxPos(w)
}
// Next returns (n, true), where n is the smallest element of S such that m < n,
// or (0, false) if no such element exists.
func (S *Set) Next(m int) (n int, found bool) {
d := S.data
len := len(d)
if len == 0 {
return
}
if min := S.min; m < min {
return min, true
}
i := len - 1
if max := i<<shift + MaxPos(d[i]); m >= max {
return
}
i = m >> shift
s := 1 + uint(m&mask)
w := d[i] >> s << s // Zero out bits for numbers ≤ m.
for w == 0 {
i++
w = d[i]
}
return i<<shift + MinPos(w), true
}
// Previous returns (n, true), where n is the largest element of S such that n < m,
// or (0, false) if no such element exists.
func (S *Set) Previous(m int) (n int, found bool) {
d := S.data
len := len(d)
if len == 0 || m <= S.min {
return
}
i := len - 1
if max := i<<shift + MaxPos(d[i]); m > max {
return max, true
}
i = m >> shift
s := bpw - uint(m&mask)
w := d[i] << s >> s // Zero out bits for numbers ≥ m.
for w == 0 {
i--
w = d[i]
}
return i<<shift + MaxPos(w), true
}
// RemoveRange removes all integers between m and n-1, m ≤ n,
// setting S to S ∖ {m..n-1}, and returns the updated set.
func (S *Set) RemoveRange(m, n int) *Set {
if m == n && m >= 0 {
return S
}
if m > n || m < 0 {
panic("Set: RemoveRange(" + strconv.Itoa(m) + ", " + strconv.Itoa(n) + ") bounds out of range")
}
n--
d := S.data
low, high := m>>shift, n>>shift
// Range does not intersect S.
if n < S.min || low >= len(d) {
return S
}
// Bottom of range undershoots S.
if m < S.min {
low = S.min >> shift // low ≤ high still holds, since S.min ≤ n.
m = 0 // To assure that m&mask == 0 below.
}
// Top of range overshoots S.
if len(d) <= high {
high = len(d) - 1 // low ≤ high still holds, since low < len(d).
n = bpw - 1 // To assure that n&mask == bpw-1 below.
}
if low == high { // Range fits in one word
d[low] &^= bitMask(m&mask, n&mask)
} else { // Range spans at least two words
d[low] &^= bitMask(m&mask, bpw-1)
for i := low + 1; i < high; i++ {
d[i] = 0
}
d[high] &^= bitMask(0, n&mask)
}
S.trim()
if m <= S.min {
S.min = findMinFrom(S.min, S.data)
}
return S
}
// Clear removes all elements and returns the updated empty set.
func (S *Set) Clear() *Set {
S.realloc(0)
S.min = 0
return S
}
// Flip removes n from S if it is present, otherwise it adds n,
// setting S to S ∆ {n}, and returns the updated set.
func (S *Set) Flip(n int) *Set {
if n < 0 {
panic("Set: Flip(" + strconv.Itoa(n) + ") index out of range")
}
if len(S.data) == 0 { // Set correct minimum when S empty.
S.min = n
}
i := n >> shift
if i >= len(S.data) {
S.resize(i + 1)
}
S.data[i] ^= 1 << uint(n&mask)
S.trim()
if n <= S.min {
// If flip removed S.min, we must search for a new minimum.
// If n < S.min, the search will find n right away.
S.min = findMinFrom(n, S.data)
}
return S
}
// FlipRange flips all elements in the range m..n-1, m ≤ n,
// setting S to S ∆ {m..n-1}, and returns the updated set.
func (S *Set) FlipRange(m, n int) *Set {
if m == n && m >= 0 {
return S
}
if m > n || m < 0 {
panic("Set: FlipRange(" + strconv.Itoa(m) + ", " + strconv.Itoa(n) + ") bounds out of range")
}
d := S.data
if len(d) == 0 { // Set correct minimum when S empty.
S.min = m
}
n--
low, high := m>>shift, n>>shift
if high >= len(d) {
S.resize(high + 1)
d = S.data
}
if low == high { // Range fits in one word.
d[low] ^= bitMask(m&mask, n&mask)
} else { // Range spans at least two words.
d[low] ^= bitMask(m&mask, bpw-1)
for i := low + 1; i < high; i++ {
d[i] ^= maxw
}
d[high] ^= bitMask(0, n&mask)
}
S.trim()
// If S.min < m, the minimum does not change.
if m <= S.min {
// The new minimum can't be smaller than m.
S.min = findMinFrom(m, S.data)
}
return S
}
// Contains returns true if n, n ≥ 0, is an element of S.
func (S *Set) Contains(n int) bool {
d := S.data
i := n >> shift
if i >= len(d) {
return false
}
return d[i]&(1<<uint(n&mask)) != 0
}
// Size returns |S|, the number of elements in S.
// This method scans the set. To check if a set is empty,
// consider using the more efficient IsEmpty.
func (S *Set) Size() int {
d := S.data
n := 0
for i, l := S.min>>shift, len(d); i < l; i++ {
if w := d[i]; w != 0 {
n += Count(w)
}
}
return n
}
// IsEmpty returns true if S = ∅.
func (S *Set) IsEmpty() bool {
return len(S.data) == 0
}
// Equals returns true if A and B contain the same elements.
func (A *Set) Equals(B *Set) bool {
if A == B {
return true
}
if A.min != B.min {
return false
}
a, b := A.data, B.data
if len(a) != len(b) {
return false
}
for i, l := A.min>>shift, len(a); i < l; i++ {
if a[i] != b[i] {
return false
}
}
return true
}
// SubsetOf returns true if A ⊆ B.
func (A *Set) SubsetOf(B *Set) bool {
if A == B {
return true
}
a, b := A.data, B.data
if len(a) > len(b) {
return false
}
if len(a) != 0 && A.min < B.min {
return false
}
for i, l := A.min>>shift, len(a); i < l; i++ {
if a[i]&^b[i] != 0 {
return false
}
}
return true
}
// Intersects returns true if A and B overlap, i.e. A ∩ B ≠ ∅.
func (A *Set) Intersects(B *Set) bool {
a, b := A.data, B.data
if len(a) == 0 || len(b) == 0 {
return false
}
if A == B { // Notice that both sets are nonempty.
return true
}
m := min(len(a), len(b))
for i := max(A.min, B.min) >> shift; i < m; i++ {
if a[i]&b[i] != 0 {
return true
}
}
return false
}
// And creates a new intersection S = A ∩ B that consists of all
// elements that belong to both A and B.
func (A *Set) And(B *Set) (S *Set) {
return new(Set).SetAnd(A, B)
}
// Or creates a new union S = A ∪ B that contains all
// elements that belong to either A or B.
func (A *Set) Or(B *Set) (S *Set) {
return new(Set).SetOr(A, B)
}
// AndNot creates a new set difference S = A ∖ B that
// consists of all elements that belong to A, but not to B.
func (A *Set) AndNot(B *Set) (S *Set) {
return new(Set).SetAndNot(A, B)
}
// Xor creates a new symmetric difference S = A ∆ B = (A ∪ B) ∖ (A ∩ B)
// that consists of all elements that belong to either A or B, but not to both.
func (A *Set) Xor(B *Set) (S *Set) {
return new(Set).SetXor(A, B)
}
// SetWord interprets w as a bitset with numbers in the range 64i to 64i + 63,
// where 0 ≤ i ≤ ⌊MaxInt/64⌋, overwrites this range in S with w, and returns S.
func (S *Set) SetWord(i int, w uint64) *Set {
if i > MaxInt/64 {
panic("Set: SetWord(" + strconv.Itoa(i) + ", 0x" + strconv.FormatUint(w, 16) +
") index out of range")
}
if w == 0 && i >= len(S.data) {
return S
}
if len := len(S.data); i >= len {
if len == 0 { // Set tentative minimum when S is empty.
S.min = 64 * i
}
S.resize(i + 1)
}
S.data[i] = w
if w == 0 && i == len(S.data)-1 {
S.trim()
}
if mi := S.min >> shift; i < mi && w != 0 || i == mi {
S.min = findMinFrom(64*i, S.data)
}
return S
}
// Word returns the range 64i to 64i + 63 of S as a bitset represented by w.
func (S *Set) Word(i int) (w uint64) {
if i < len(S.data) {
w = S.data[i]
}
return
}
// Set sets S to A and returns S.
func (S *Set) Set(A *Set) *Set {
S.realloc(len(A.data))
low := min(A.min>>shift, S.min>>shift) // Words below this index are all zero,
copy(S.data[low:], A.data[low:]) // so there is no need to copy them.
S.min = A.min
return S
}
// SetAnd sets S to the intersection A ∩ B and returns S.
func (S *Set) SetAnd(A, B *Set) *Set {
a, b := A.data, B.data
la, lb := len(a), len(b)
ma, mb, ms := A.min, B.min, S.min
// Check if ranges overlap.
if la == 0 || lb == 0 || la <= mb>>shift || lb <= ma>>shift {
return S.Clear()
}
// S.data[i], i < low, are words that should be zero and already are.
low := min(max(ma, mb), ms) >> shift
// Find last nonzero word in result.
i := min(la, lb) - 1
for i >= 0 && a[i]&b[i] == 0 {
i--
}
if S == A || S == B {
S.resize(i + 1)
} else {
S.realloc(i + 1)
}
for ; i >= low; i-- {
S.data[i] = a[i] & b[i]
}
S.min = findMinFrom(max(ma, mb), S.data)
return S
}
// SetAndNot sets S to the set difference A ∖ B and returns S.
func (S *Set) SetAndNot(A, B *Set) *Set {
a, b := A.data, B.data
la, lb := len(a), len(b)
ma, mb, ms := A.min, B.min, S.min
// Check if ranges overlap.
if la == 0 || lb == 0 || la <= mb>>shift || lb <= ma>>shift {
return S.Set(A)
}
// S.data[i], i < low, are words that should be zero and already are.
low := min(ma, ms) >> shift
// Result requires len(a) words if len(a) > len(b),
// otherwise find last nonzero word in result.
i := la - 1
if la <= lb {
for i >= 0 && a[i]&^b[i] == 0 {
i--
}
}
if S == A || S == B {
S.resize(i + 1)
} else {
S.realloc(i + 1)
}
d := S.data
if m := max(lb, low); m <= i {
copy(d[m:i+1], a[m:i+1])
i = m - 1
}
for ; i >= low; i-- {
d[i] = a[i] &^ b[i]
}
if A.min < B.min { // Minimum can't have changed.
S.min = A.min
} else {
S.min = findMinFrom(ma, d) // can't be smaller than previous A.min.
}
return S
}
// SetOr sets S to the union A ∪ B and returns S.
func (S *Set) SetOr(A, B *Set) *Set {
// Swap, if necessary, to make A shorter than B.
if len(A.data) > len(B.data) {
A, B = B, A
}
a, b := A.data, B.data
la, lb := len(a), len(b)
ma, mb, ms := A.min, B.min, S.min
i := lb - 1
if S == A || S == B {
S.resize(i + 1)
} else {
S.realloc(i + 1)
}
d := S.data
copy(d[la:i+1], b[la:i+1])
i = la - 1
// S.data[i], i < low, are words that should be zero and already are.
low := min(min(ma, mb), ms) >> shift
for ; i >= low; i-- {
d[i] = a[i] | b[i]
}
if la == 0 {
S.min = mb
} else if lb == 0 {
S.min = ma
} else {
S.min = min(ma, mb)
}
return S
}
// SetXor sets S to the symmetric difference A ∆ B = (A ∪ B) ∖ (A ∩ B)
// and returns S.
func (S *Set) SetXor(A, B *Set) *Set {
// Swap, if necessary, to make A shorter than B.
if len(A.data) > len(B.data) {
A, B = B, A
}
a, b := A.data, B.data
la, lb := len(a), len(b)
ma, mb, ms := A.min, B.min, S.min
i := lb - 1
if la == lb { // The only case where result may be shorter than len(b).
low := min(ma, mb) >> shift
for i >= low && a[i]^b[i] == 0 {
i--
}
if i == low-1 { // Only zero elements left.
return S.Clear()
}
}
if S == A || S == B {
S.resize(i + 1)
} else {
S.realloc(i + 1)
}
d := S.data
if la <= i {
copy(d[la:i+1], b[la:i+1])
i = la - 1
}
// S.data[i], i < low, are words that should be zero and already are.
low := min(min(ma, mb), ms) >> shift
for ; i >= low; i-- {
d[i] = a[i] ^ b[i]
}
S.min = findMinFrom(min(ma, mb), d)
return S
}
// Do calls function f for each element n ∊ S in numerical order.
// It is safe for f to add or remove elements e, e ≤ n, from S.
// The behavior of Do is undefined if f changes the set in any other way.
func (S *Set) Do(f func(n int)) {
d := S.data
for i, l := S.min>>shift, len(d); i < l; i++ {
w := d[i]
if w == 0 {
continue
}
n := i << shift // element represented by w&1
for w != 0 {
b := MinPos(w)
n += b
f(n)
n++
w >>= uint(b + 1)
for w&1 != 0 { // common case
f(n)
n++
w >>= 1
}
}
}
}
// String returns a string representation of S.
// The elements are listed in ascending order, enclosed by braces,
// and separated by ", ". Runs of at least three elements a, a+1, ..., b
// are given as "a..b".
//
// For example, the set {1, 2, 6, 5, 3} is represented as "{1..3, 5, 6}".
func (S *Set) String() string {
sb := new(bytes.Buffer)
sb.WriteString("{")
a, b := -1, -2 // keeps track of a range a..b of elements
S.Do(func(n int) {
if n == b+1 { // Increase current range from a..b to a..b+1.
b = n
return
}
writeRange(sb, a, b)
a, b = n, n // Start new range.
})
writeRange(sb, a, b)
if S.Size() > 0 {
sb.Truncate(sb.Len() - 2) // Remove trailing ", ".
}
sb.WriteString("}")
return sb.String()
}
// writeRange writes either "", "a", "a, b, " or "a..b, " to buffer.
func writeRange(sb *bytes.Buffer, a, b int) {
switch {
case a > b:
// sb.WriteString(sb, "")
case a == b:
sb.WriteString(strconv.Itoa(a))
sb.WriteString(", ")
case a+1 == b:
sb.WriteString(strconv.Itoa(a))
sb.WriteString(", ")
sb.WriteString(strconv.Itoa(b))
sb.WriteString(", ")
default:
sb.WriteString(strconv.Itoa(a))
sb.WriteString("..")
sb.WriteString(strconv.Itoa(b))
sb.WriteString(", ")
}
}
// resize changes the length of S.data to n, keeping old values.
// It preserves the invariant S.data[i] = 0, n ≤ i < cap(data).
func (S *Set) resize(n int) {
d := S.data
if S.realloc(n) {
low := min(S.min>>shift, len(d)) // Words below S.min>>shift are zero;
copy(S.data[low:], d[low:]) // there is no need to copy them.
}
}
// realloc creates a slice S.data of length n, possibly zeroing out old values.
// It preserves the invariant S.data[i] = 0, n ≤ i < cap(data).
// It returns true if new memory has been allocated.
func (S *Set) realloc(n int) (didAlloc bool) {
if c := cap(S.data); c < n {
S.data = make([]uint64, n, newCap(n, c))
return true
}
// Add zeroes if shrinking.
d := S.data
low := max(n, S.min>>shift) // The words d[i], i < low, are already zero.
for i := len(d) - 1; i >= low; i-- {
d[i] = 0
}
S.data = d[:n]
return false
}
// newCap suggests a new increased capacity, favoring powers of two,
// when growing a slice to length n. The suggested capacities guarantee
// linear amortized cost for repeated memory allocations.
func newCap(n, prevCap int) int {
return max(n, nextPow2(prevCap))
}
// nextPow2 returns the smallest p = 1, 2, 4, ..., 2^k such that p > n,
// or MaxInt if p > MaxInt.
func nextPow2(n int) (p int) {
if n <= 0 {
return 1
}
if k := MaxPos(uint64(n)) + 1; k < BitsPerWord-1 {
return 1 << uint(k)
}
return MaxInt
}
// trim slices S.data by removing all trailing words equal to zero.
// It preserves the invariant: S.min = min(S) if S ≠ ∅, 0 otherwise.
func (S *Set) trim() {
d := S.data
i := len(d) - 1
for i >= 0 && d[i] == 0 {
i--
}
S.data = d[:i+1]
if i == -1 {
S.min = 0
}
}
// findMinFrom finds the mininum element starting the search from n.
// It assumes that such an element exists; however, it returns 0 if
// len(data) == 0.
func findMinFrom(n int, data []uint64) int {
if len(data) == 0 {
return 0
}
i := n >> shift
w := data[i]
for w == 0 {
i++
w = data[i]
}
return i<<shift + MinPos(w)
}
// bitMask returns a bit mask with nonzero bits from m to n, 0 ≤ m ≤ n < bpw.
func bitMask(m, n int) uint64 {
return maxw >> uint(bpw-1-(n-m)) << uint(m)
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}