Copy dependencies into vendor dir, using dep
This commit is contained in:
1 parent
549ccff5eb
commit
b534ea60f5
2857 files changed
+945317
No files matched your search
+309
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
Reference in new issue
Block a user