github.com/gopherd/gonum@v0.0.4/container/intsets/sparse.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package intsets provides Sparse, a compact and fast representation
     6  // for sparse sets of int values.
     7  //
     8  // The time complexity of the operations Len, Insert, Remove and Has
     9  // is in O(n) but in practice those methods are faster and more
    10  // space-efficient than equivalent operations on sets based on the Go
    11  // map type.  The IsEmpty, Min, Max, Clear and TakeMin operations
    12  // require constant time.
    13  //
    14  package intsets
    15  
    16  // TODO(adonovan):
    17  // - Add InsertAll(...int), RemoveAll(...int)
    18  // - Add 'bool changed' results for {Intersection,Difference}With too.
    19  //
    20  // TODO(adonovan): implement Dense, a dense bit vector with a similar API.
    21  // The space usage would be proportional to Max(), not Len(), and the
    22  // implementation would be based upon big.Int.
    23  //
    24  // TODO(adonovan): opt: make UnionWith and Difference faster.
    25  // These are the hot-spots for go/pointer.
    26  
    27  import (
    28  	"bytes"
    29  	"fmt"
    30  	"math/bits"
    31  )
    32  
    33  // A Sparse is a set of int values.
    34  // Sparse operations (even queries) are not concurrency-safe.
    35  //
    36  // The zero value for Sparse is a valid empty set.
    37  //
    38  // Sparse sets must be copied using the Copy method, not by assigning
    39  // a Sparse value.
    40  //
    41  type Sparse struct {
    42  	// An uninitialized Sparse represents an empty set.
    43  	// An empty set may also be represented by
    44  	//  root.next == root.prev == &root.
    45  	//
    46  	// The root is always the block with the smallest offset.
    47  	// It can be empty, but only if it is the only block; in that case, offset is
    48  	// MaxInt (which is not a valid offset).
    49  	root block
    50  }
    51  
    52  type word uintptr
    53  
    54  const (
    55  	_m            = ^word(0)
    56  	bitsPerWord   = 8 << (_m>>8&1 + _m>>16&1 + _m>>32&1)
    57  	bitsPerBlock  = 256 // optimal value for go/pointer solver performance
    58  	wordsPerBlock = bitsPerBlock / bitsPerWord
    59  )
    60  
    61  // Limit values of implementation-specific int type.
    62  const (
    63  	MaxInt = int(^uint(0) >> 1)
    64  	MinInt = -MaxInt - 1
    65  )
    66  
    67  // popcount returns the number of set bits in w.
    68  func popcount(x word) int {
    69  	// Avoid OnesCount(uint): don't assume uint = uintptr.
    70  	if bitsPerWord == 32 {
    71  		return bits.OnesCount32(uint32(x))
    72  	} else {
    73  		return bits.OnesCount64(uint64(x))
    74  	}
    75  }
    76  
    77  // nlz returns the number of leading zeros of x.
    78  func nlz(x word) int {
    79  	// Avoid LeadingZeros(uint): don't assume uint = uintptr.
    80  	if bitsPerWord == 32 {
    81  		return bits.LeadingZeros32(uint32(x))
    82  	} else {
    83  		return bits.LeadingZeros64(uint64(x))
    84  	}
    85  }
    86  
    87  // ntz returns the number of trailing zeros of x.
    88  func ntz(x word) int {
    89  	// Avoid TrailingZeros(uint): don't assume uint = uintptr.
    90  	if bitsPerWord == 32 {
    91  		return bits.TrailingZeros32(uint32(x))
    92  	} else {
    93  		return bits.TrailingZeros64(uint64(x))
    94  	}
    95  }
    96  
    97  // -- block ------------------------------------------------------------
    98  
    99  // A set is represented as a circular doubly-linked list of blocks,
   100  // each containing an offset and a bit array of fixed size
   101  // bitsPerBlock; the blocks are ordered by increasing offset.
   102  //
   103  // The set contains an element x iff the block whose offset is x - (x
   104  // mod bitsPerBlock) has the bit (x mod bitsPerBlock) set, where mod
   105  // is the Euclidean remainder.
   106  //
   107  // A block may only be empty transiently.
   108  //
   109  type block struct {
   110  	offset     int                 // offset mod bitsPerBlock == 0
   111  	bits       [wordsPerBlock]word // contains at least one set bit
   112  	next, prev *block              // doubly-linked list of blocks
   113  }
   114  
   115  // wordMask returns the word index (in block.bits)
   116  // and single-bit mask for the block's ith bit.
   117  func wordMask(i uint) (w uint, mask word) {
   118  	w = i / bitsPerWord
   119  	mask = 1 << (i % bitsPerWord)
   120  	return
   121  }
   122  
   123  // insert sets the block b's ith bit and
   124  // returns true if it was not already set.
   125  //
   126  func (b *block) insert(i uint) bool {
   127  	w, mask := wordMask(i)
   128  	if b.bits[w]&mask == 0 {
   129  		b.bits[w] |= mask
   130  		return true
   131  	}
   132  	return false
   133  }
   134  
   135  // remove clears the block's ith bit and
   136  // returns true if the bit was previously set.
   137  // NB: may leave the block empty.
   138  //
   139  func (b *block) remove(i uint) bool {
   140  	w, mask := wordMask(i)
   141  	if b.bits[w]&mask != 0 {
   142  		b.bits[w] &^= mask
   143  		return true
   144  	}
   145  	return false
   146  }
   147  
   148  // has reports whether the block's ith bit is set.
   149  func (b *block) has(i uint) bool {
   150  	w, mask := wordMask(i)
   151  	return b.bits[w]&mask != 0
   152  }
   153  
   154  // empty reports whether b.len()==0, but more efficiently.
   155  func (b *block) empty() bool {
   156  	for _, w := range b.bits {
   157  		if w != 0 {
   158  			return false
   159  		}
   160  	}
   161  	return true
   162  }
   163  
   164  // len returns the number of set bits in block b.
   165  func (b *block) len() int {
   166  	var l int
   167  	for _, w := range b.bits {
   168  		l += popcount(w)
   169  	}
   170  	return l
   171  }
   172  
   173  // max returns the maximum element of the block.
   174  // The block must not be empty.
   175  func (b *block) max() int {
   176  	bi := b.offset + bitsPerBlock
   177  	// Decrement bi by number of high zeros in last.bits.
   178  	for i := len(b.bits) - 1; i >= 0; i-- {
   179  		if w := b.bits[i]; w != 0 {
   180  			return bi - nlz(w) - 1
   181  		}
   182  		bi -= bitsPerWord
   183  	}
   184  	panic("BUG: empty block")
   185  }
   186  
   187  // min returns the minimum element of the block,
   188  // and also removes it if take is set.
   189  // The block must not be initially empty.
   190  // NB: may leave the block empty.
   191  func (b *block) min(take bool) int {
   192  	for i, w := range b.bits {
   193  		if w != 0 {
   194  			tz := ntz(w)
   195  			if take {
   196  				b.bits[i] = w &^ (1 << uint(tz))
   197  			}
   198  			return b.offset + int(i*bitsPerWord) + tz
   199  		}
   200  	}
   201  	panic("BUG: empty block")
   202  }
   203  
   204  // lowerBound returns the smallest element of the block that is greater than or
   205  // equal to the element corresponding to the ith bit. If there is no such
   206  // element, the second return value is false.
   207  func (b *block) lowerBound(i uint) (int, bool) {
   208  	w := i / bitsPerWord
   209  	bit := i % bitsPerWord
   210  
   211  	if val := b.bits[w] >> bit; val != 0 {
   212  		return b.offset + int(i) + ntz(val), true
   213  	}
   214  
   215  	for w++; w < wordsPerBlock; w++ {
   216  		if val := b.bits[w]; val != 0 {
   217  			return b.offset + int(w*bitsPerWord) + ntz(val), true
   218  		}
   219  	}
   220  
   221  	return 0, false
   222  }
   223  
   224  // forEach calls f for each element of block b.
   225  // f must not mutate b's enclosing Sparse.
   226  func (b *block) forEach(f func(int)) {
   227  	for i, w := range b.bits {
   228  		offset := b.offset + i*bitsPerWord
   229  		for bi := 0; w != 0 && bi < bitsPerWord; bi++ {
   230  			if w&1 != 0 {
   231  				f(offset)
   232  			}
   233  			offset++
   234  			w >>= 1
   235  		}
   236  	}
   237  }
   238  
   239  // offsetAndBitIndex returns the offset of the block that would
   240  // contain x and the bit index of x within that block.
   241  //
   242  func offsetAndBitIndex(x int) (int, uint) {
   243  	mod := x % bitsPerBlock
   244  	if mod < 0 {
   245  		// Euclidean (non-negative) remainder
   246  		mod += bitsPerBlock
   247  	}
   248  	return x - mod, uint(mod)
   249  }
   250  
   251  // -- Sparse --------------------------------------------------------------
   252  
   253  // none is a shared, empty, sentinel block that indicates the end of a block
   254  // list.
   255  var none block
   256  
   257  // Dummy type used to generate an implicit panic. This must be defined at the
   258  // package level; if it is defined inside a function, it prevents the inlining
   259  // of that function.
   260  type to_copy_a_sparse_you_must_call_its_Copy_method struct{}
   261  
   262  // init ensures s is properly initialized.
   263  func (s *Sparse) init() {
   264  	root := &s.root
   265  	if root.next == nil {
   266  		root.offset = MaxInt
   267  		root.next = root
   268  		root.prev = root
   269  	} else if root.next.prev != root {
   270  		// Copying a Sparse x leads to pernicious corruption: the
   271  		// new Sparse y shares the old linked list, but iteration
   272  		// on y will never encounter &y.root so it goes into a
   273  		// loop.  Fail fast before this occurs.
   274  		// We don't want to call panic here because it prevents the
   275  		// inlining of this function.
   276  		_ = (interface{}(nil)).(to_copy_a_sparse_you_must_call_its_Copy_method)
   277  	}
   278  }
   279  
   280  func (s *Sparse) first() *block {
   281  	s.init()
   282  	if s.root.offset == MaxInt {
   283  		return &none
   284  	}
   285  	return &s.root
   286  }
   287  
   288  // next returns the next block in the list, or end if b is the last block.
   289  func (s *Sparse) next(b *block) *block {
   290  	if b.next == &s.root {
   291  		return &none
   292  	}
   293  	return b.next
   294  }
   295  
   296  // prev returns the previous block in the list, or end if b is the first block.
   297  func (s *Sparse) prev(b *block) *block {
   298  	if b.prev == &s.root {
   299  		return &none
   300  	}
   301  	return b.prev
   302  }
   303  
   304  // IsEmpty reports whether the set s is empty.
   305  func (s *Sparse) IsEmpty() bool {
   306  	return s.root.next == nil || s.root.offset == MaxInt
   307  }
   308  
   309  // Len returns the number of elements in the set s.
   310  func (s *Sparse) Len() int {
   311  	var l int
   312  	for b := s.first(); b != &none; b = s.next(b) {
   313  		l += b.len()
   314  	}
   315  	return l
   316  }
   317  
   318  // Max returns the maximum element of the set s, or MinInt if s is empty.
   319  func (s *Sparse) Max() int {
   320  	if s.IsEmpty() {
   321  		return MinInt
   322  	}
   323  	return s.root.prev.max()
   324  }
   325  
   326  // Min returns the minimum element of the set s, or MaxInt if s is empty.
   327  func (s *Sparse) Min() int {
   328  	if s.IsEmpty() {
   329  		return MaxInt
   330  	}
   331  	return s.root.min(false)
   332  }
   333  
   334  // LowerBound returns the smallest element >= x, or MaxInt if there is no such
   335  // element.
   336  func (s *Sparse) LowerBound(x int) int {
   337  	offset, i := offsetAndBitIndex(x)
   338  	for b := s.first(); b != &none; b = s.next(b) {
   339  		if b.offset > offset {
   340  			return b.min(false)
   341  		}
   342  		if b.offset == offset {
   343  			if y, ok := b.lowerBound(i); ok {
   344  				return y
   345  			}
   346  		}
   347  	}
   348  	return MaxInt
   349  }
   350  
   351  // block returns the block that would contain offset,
   352  // or nil if s contains no such block.
   353  // Precondition: offset is a multiple of bitsPerBlock.
   354  func (s *Sparse) block(offset int) *block {
   355  	for b := s.first(); b != &none && b.offset <= offset; b = s.next(b) {
   356  		if b.offset == offset {
   357  			return b
   358  		}
   359  	}
   360  	return nil
   361  }
   362  
   363  // Insert adds x to the set s, and reports whether the set grew.
   364  func (s *Sparse) Insert(x int) bool {
   365  	offset, i := offsetAndBitIndex(x)
   366  
   367  	b := s.first()
   368  	for ; b != &none && b.offset <= offset; b = s.next(b) {
   369  		if b.offset == offset {
   370  			return b.insert(i)
   371  		}
   372  	}
   373  
   374  	// Insert new block before b.
   375  	new := s.insertBlockBefore(b)
   376  	new.offset = offset
   377  	return new.insert(i)
   378  }
   379  
   380  // removeBlock removes a block and returns the block that followed it (or end if
   381  // it was the last block).
   382  func (s *Sparse) removeBlock(b *block) *block {
   383  	if b != &s.root {
   384  		b.prev.next = b.next
   385  		b.next.prev = b.prev
   386  		if b.next == &s.root {
   387  			return &none
   388  		}
   389  		return b.next
   390  	}
   391  
   392  	first := s.root.next
   393  	if first == &s.root {
   394  		// This was the only block.
   395  		s.Clear()
   396  		return &none
   397  	}
   398  	s.root.offset = first.offset
   399  	s.root.bits = first.bits
   400  	if first.next == &s.root {
   401  		// Single block remaining.
   402  		s.root.next = &s.root
   403  		s.root.prev = &s.root
   404  	} else {
   405  		s.root.next = first.next
   406  		first.next.prev = &s.root
   407  	}
   408  	return &s.root
   409  }
   410  
   411  // Remove removes x from the set s, and reports whether the set shrank.
   412  func (s *Sparse) Remove(x int) bool {
   413  	offset, i := offsetAndBitIndex(x)
   414  	if b := s.block(offset); b != nil {
   415  		if !b.remove(i) {
   416  			return false
   417  		}
   418  		if b.empty() {
   419  			s.removeBlock(b)
   420  		}
   421  		return true
   422  	}
   423  	return false
   424  }
   425  
   426  // Clear removes all elements from the set s.
   427  func (s *Sparse) Clear() {
   428  	s.root = block{
   429  		offset: MaxInt,
   430  		next:   &s.root,
   431  		prev:   &s.root,
   432  	}
   433  }
   434  
   435  // If set s is non-empty, TakeMin sets *p to the minimum element of
   436  // the set s, removes that element from the set and returns true.
   437  // Otherwise, it returns false and *p is undefined.
   438  //
   439  // This method may be used for iteration over a worklist like so:
   440  //
   441  // 	var x int
   442  // 	for worklist.TakeMin(&x) { use(x) }
   443  //
   444  func (s *Sparse) TakeMin(p *int) bool {
   445  	if s.IsEmpty() {
   446  		return false
   447  	}
   448  	*p = s.root.min(true)
   449  	if s.root.empty() {
   450  		s.removeBlock(&s.root)
   451  	}
   452  	return true
   453  }
   454  
   455  // Has reports whether x is an element of the set s.
   456  func (s *Sparse) Has(x int) bool {
   457  	offset, i := offsetAndBitIndex(x)
   458  	if b := s.block(offset); b != nil {
   459  		return b.has(i)
   460  	}
   461  	return false
   462  }
   463  
   464  // forEach applies function f to each element of the set s in order.
   465  //
   466  // f must not mutate s.  Consequently, forEach is not safe to expose
   467  // to clients.  In any case, using "range s.AppendTo()" allows more
   468  // natural control flow with continue/break/return.
   469  //
   470  func (s *Sparse) forEach(f func(int)) {
   471  	for b := s.first(); b != &none; b = s.next(b) {
   472  		b.forEach(f)
   473  	}
   474  }
   475  
   476  // Copy sets s to the value of x.
   477  func (s *Sparse) Copy(x *Sparse) {
   478  	if s == x {
   479  		return
   480  	}
   481  
   482  	xb := x.first()
   483  	sb := s.first()
   484  	for xb != &none {
   485  		if sb == &none {
   486  			sb = s.insertBlockBefore(sb)
   487  		}
   488  		sb.offset = xb.offset
   489  		sb.bits = xb.bits
   490  		xb = x.next(xb)
   491  		sb = s.next(sb)
   492  	}
   493  	s.discardTail(sb)
   494  }
   495  
   496  // insertBlockBefore returns a new block, inserting it before next.
   497  // If next is the root, the root is replaced. If next is end, the block is
   498  // inserted at the end.
   499  func (s *Sparse) insertBlockBefore(next *block) *block {
   500  	if s.IsEmpty() {
   501  		if next != &none {
   502  			panic("BUG: passed block with empty set")
   503  		}
   504  		return &s.root
   505  	}
   506  
   507  	if next == &s.root {
   508  		// Special case: we need to create a new block that will become the root
   509  		// block.The old root block becomes the second block.
   510  		second := s.root
   511  		s.root = block{
   512  			next: &second,
   513  		}
   514  		if second.next == &s.root {
   515  			s.root.prev = &second
   516  		} else {
   517  			s.root.prev = second.prev
   518  			second.next.prev = &second
   519  			second.prev = &s.root
   520  		}
   521  		return &s.root
   522  	}
   523  	if next == &none {
   524  		// Insert before root.
   525  		next = &s.root
   526  	}
   527  	b := new(block)
   528  	b.next = next
   529  	b.prev = next.prev
   530  	b.prev.next = b
   531  	next.prev = b
   532  	return b
   533  }
   534  
   535  // discardTail removes block b and all its successors from s.
   536  func (s *Sparse) discardTail(b *block) {
   537  	if b != &none {
   538  		if b == &s.root {
   539  			s.Clear()
   540  		} else {
   541  			b.prev.next = &s.root
   542  			s.root.prev = b.prev
   543  		}
   544  	}
   545  }
   546  
   547  // IntersectionWith sets s to the intersection s ∩ x.
   548  func (s *Sparse) IntersectionWith(x *Sparse) {
   549  	if s == x {
   550  		return
   551  	}
   552  
   553  	xb := x.first()
   554  	sb := s.first()
   555  	for xb != &none && sb != &none {
   556  		switch {
   557  		case xb.offset < sb.offset:
   558  			xb = x.next(xb)
   559  
   560  		case xb.offset > sb.offset:
   561  			sb = s.removeBlock(sb)
   562  
   563  		default:
   564  			var sum word
   565  			for i := range sb.bits {
   566  				r := xb.bits[i] & sb.bits[i]
   567  				sb.bits[i] = r
   568  				sum |= r
   569  			}
   570  			if sum != 0 {
   571  				sb = s.next(sb)
   572  			} else {
   573  				// sb will be overwritten or removed
   574  			}
   575  
   576  			xb = x.next(xb)
   577  		}
   578  	}
   579  
   580  	s.discardTail(sb)
   581  }
   582  
   583  // Intersection sets s to the intersection x ∩ y.
   584  func (s *Sparse) Intersection(x, y *Sparse) {
   585  	switch {
   586  	case s == x:
   587  		s.IntersectionWith(y)
   588  		return
   589  	case s == y:
   590  		s.IntersectionWith(x)
   591  		return
   592  	case x == y:
   593  		s.Copy(x)
   594  		return
   595  	}
   596  
   597  	xb := x.first()
   598  	yb := y.first()
   599  	sb := s.first()
   600  	for xb != &none && yb != &none {
   601  		switch {
   602  		case xb.offset < yb.offset:
   603  			xb = x.next(xb)
   604  			continue
   605  		case xb.offset > yb.offset:
   606  			yb = y.next(yb)
   607  			continue
   608  		}
   609  
   610  		if sb == &none {
   611  			sb = s.insertBlockBefore(sb)
   612  		}
   613  		sb.offset = xb.offset
   614  
   615  		var sum word
   616  		for i := range sb.bits {
   617  			r := xb.bits[i] & yb.bits[i]
   618  			sb.bits[i] = r
   619  			sum |= r
   620  		}
   621  		if sum != 0 {
   622  			sb = s.next(sb)
   623  		} else {
   624  			// sb will be overwritten or removed
   625  		}
   626  
   627  		xb = x.next(xb)
   628  		yb = y.next(yb)
   629  	}
   630  
   631  	s.discardTail(sb)
   632  }
   633  
   634  // Intersects reports whether s ∩ x ≠ ∅.
   635  func (s *Sparse) Intersects(x *Sparse) bool {
   636  	sb := s.first()
   637  	xb := x.first()
   638  	for sb != &none && xb != &none {
   639  		switch {
   640  		case xb.offset < sb.offset:
   641  			xb = x.next(xb)
   642  		case xb.offset > sb.offset:
   643  			sb = s.next(sb)
   644  		default:
   645  			for i := range sb.bits {
   646  				if sb.bits[i]&xb.bits[i] != 0 {
   647  					return true
   648  				}
   649  			}
   650  			sb = s.next(sb)
   651  			xb = x.next(xb)
   652  		}
   653  	}
   654  	return false
   655  }
   656  
   657  // UnionWith sets s to the union s ∪ x, and reports whether s grew.
   658  func (s *Sparse) UnionWith(x *Sparse) bool {
   659  	if s == x {
   660  		return false
   661  	}
   662  
   663  	var changed bool
   664  	xb := x.first()
   665  	sb := s.first()
   666  	for xb != &none {
   667  		if sb != &none && sb.offset == xb.offset {
   668  			for i := range xb.bits {
   669  				union := sb.bits[i] | xb.bits[i]
   670  				if sb.bits[i] != union {
   671  					sb.bits[i] = union
   672  					changed = true
   673  				}
   674  			}
   675  			xb = x.next(xb)
   676  		} else if sb == &none || sb.offset > xb.offset {
   677  			sb = s.insertBlockBefore(sb)
   678  			sb.offset = xb.offset
   679  			sb.bits = xb.bits
   680  			changed = true
   681  
   682  			xb = x.next(xb)
   683  		}
   684  		sb = s.next(sb)
   685  	}
   686  	return changed
   687  }
   688  
   689  // Union sets s to the union x ∪ y.
   690  func (s *Sparse) Union(x, y *Sparse) {
   691  	switch {
   692  	case x == y:
   693  		s.Copy(x)
   694  		return
   695  	case s == x:
   696  		s.UnionWith(y)
   697  		return
   698  	case s == y:
   699  		s.UnionWith(x)
   700  		return
   701  	}
   702  
   703  	xb := x.first()
   704  	yb := y.first()
   705  	sb := s.first()
   706  	for xb != &none || yb != &none {
   707  		if sb == &none {
   708  			sb = s.insertBlockBefore(sb)
   709  		}
   710  		switch {
   711  		case yb == &none || (xb != &none && xb.offset < yb.offset):
   712  			sb.offset = xb.offset
   713  			sb.bits = xb.bits
   714  			xb = x.next(xb)
   715  
   716  		case xb == &none || (yb != &none && yb.offset < xb.offset):
   717  			sb.offset = yb.offset
   718  			sb.bits = yb.bits
   719  			yb = y.next(yb)
   720  
   721  		default:
   722  			sb.offset = xb.offset
   723  			for i := range xb.bits {
   724  				sb.bits[i] = xb.bits[i] | yb.bits[i]
   725  			}
   726  			xb = x.next(xb)
   727  			yb = y.next(yb)
   728  		}
   729  		sb = s.next(sb)
   730  	}
   731  
   732  	s.discardTail(sb)
   733  }
   734  
   735  // DifferenceWith sets s to the difference s ∖ x.
   736  func (s *Sparse) DifferenceWith(x *Sparse) {
   737  	if s == x {
   738  		s.Clear()
   739  		return
   740  	}
   741  
   742  	xb := x.first()
   743  	sb := s.first()
   744  	for xb != &none && sb != &none {
   745  		switch {
   746  		case xb.offset > sb.offset:
   747  			sb = s.next(sb)
   748  
   749  		case xb.offset < sb.offset:
   750  			xb = x.next(xb)
   751  
   752  		default:
   753  			var sum word
   754  			for i := range sb.bits {
   755  				r := sb.bits[i] & ^xb.bits[i]
   756  				sb.bits[i] = r
   757  				sum |= r
   758  			}
   759  			if sum == 0 {
   760  				sb = s.removeBlock(sb)
   761  			} else {
   762  				sb = s.next(sb)
   763  			}
   764  			xb = x.next(xb)
   765  		}
   766  	}
   767  }
   768  
   769  // Difference sets s to the difference x ∖ y.
   770  func (s *Sparse) Difference(x, y *Sparse) {
   771  	switch {
   772  	case x == y:
   773  		s.Clear()
   774  		return
   775  	case s == x:
   776  		s.DifferenceWith(y)
   777  		return
   778  	case s == y:
   779  		var y2 Sparse
   780  		y2.Copy(y)
   781  		s.Difference(x, &y2)
   782  		return
   783  	}
   784  
   785  	xb := x.first()
   786  	yb := y.first()
   787  	sb := s.first()
   788  	for xb != &none && yb != &none {
   789  		if xb.offset > yb.offset {
   790  			// y has block, x has &none
   791  			yb = y.next(yb)
   792  			continue
   793  		}
   794  
   795  		if sb == &none {
   796  			sb = s.insertBlockBefore(sb)
   797  		}
   798  		sb.offset = xb.offset
   799  
   800  		switch {
   801  		case xb.offset < yb.offset:
   802  			// x has block, y has &none
   803  			sb.bits = xb.bits
   804  
   805  			sb = s.next(sb)
   806  
   807  		default:
   808  			// x and y have corresponding blocks
   809  			var sum word
   810  			for i := range sb.bits {
   811  				r := xb.bits[i] & ^yb.bits[i]
   812  				sb.bits[i] = r
   813  				sum |= r
   814  			}
   815  			if sum != 0 {
   816  				sb = s.next(sb)
   817  			} else {
   818  				// sb will be overwritten or removed
   819  			}
   820  
   821  			yb = y.next(yb)
   822  		}
   823  		xb = x.next(xb)
   824  	}
   825  
   826  	for xb != &none {
   827  		if sb == &none {
   828  			sb = s.insertBlockBefore(sb)
   829  		}
   830  		sb.offset = xb.offset
   831  		sb.bits = xb.bits
   832  		sb = s.next(sb)
   833  
   834  		xb = x.next(xb)
   835  	}
   836  
   837  	s.discardTail(sb)
   838  }
   839  
   840  // SymmetricDifferenceWith sets s to the symmetric difference s ∆ x.
   841  func (s *Sparse) SymmetricDifferenceWith(x *Sparse) {
   842  	if s == x {
   843  		s.Clear()
   844  		return
   845  	}
   846  
   847  	sb := s.first()
   848  	xb := x.first()
   849  	for xb != &none && sb != &none {
   850  		switch {
   851  		case sb.offset < xb.offset:
   852  			sb = s.next(sb)
   853  		case xb.offset < sb.offset:
   854  			nb := s.insertBlockBefore(sb)
   855  			nb.offset = xb.offset
   856  			nb.bits = xb.bits
   857  			xb = x.next(xb)
   858  		default:
   859  			var sum word
   860  			for i := range sb.bits {
   861  				r := sb.bits[i] ^ xb.bits[i]
   862  				sb.bits[i] = r
   863  				sum |= r
   864  			}
   865  			if sum == 0 {
   866  				sb = s.removeBlock(sb)
   867  			} else {
   868  				sb = s.next(sb)
   869  			}
   870  			xb = x.next(xb)
   871  		}
   872  	}
   873  
   874  	for xb != &none { // append the tail of x to s
   875  		sb = s.insertBlockBefore(sb)
   876  		sb.offset = xb.offset
   877  		sb.bits = xb.bits
   878  		sb = s.next(sb)
   879  		xb = x.next(xb)
   880  	}
   881  }
   882  
   883  // SymmetricDifference sets s to the symmetric difference x ∆ y.
   884  func (s *Sparse) SymmetricDifference(x, y *Sparse) {
   885  	switch {
   886  	case x == y:
   887  		s.Clear()
   888  		return
   889  	case s == x:
   890  		s.SymmetricDifferenceWith(y)
   891  		return
   892  	case s == y:
   893  		s.SymmetricDifferenceWith(x)
   894  		return
   895  	}
   896  
   897  	sb := s.first()
   898  	xb := x.first()
   899  	yb := y.first()
   900  	for xb != &none && yb != &none {
   901  		if sb == &none {
   902  			sb = s.insertBlockBefore(sb)
   903  		}
   904  		switch {
   905  		case yb.offset < xb.offset:
   906  			sb.offset = yb.offset
   907  			sb.bits = yb.bits
   908  			sb = s.next(sb)
   909  			yb = y.next(yb)
   910  		case xb.offset < yb.offset:
   911  			sb.offset = xb.offset
   912  			sb.bits = xb.bits
   913  			sb = s.next(sb)
   914  			xb = x.next(xb)
   915  		default:
   916  			var sum word
   917  			for i := range sb.bits {
   918  				r := xb.bits[i] ^ yb.bits[i]
   919  				sb.bits[i] = r
   920  				sum |= r
   921  			}
   922  			if sum != 0 {
   923  				sb.offset = xb.offset
   924  				sb = s.next(sb)
   925  			}
   926  			xb = x.next(xb)
   927  			yb = y.next(yb)
   928  		}
   929  	}
   930  
   931  	for xb != &none { // append the tail of x to s
   932  		if sb == &none {
   933  			sb = s.insertBlockBefore(sb)
   934  		}
   935  		sb.offset = xb.offset
   936  		sb.bits = xb.bits
   937  		sb = s.next(sb)
   938  		xb = x.next(xb)
   939  	}
   940  
   941  	for yb != &none { // append the tail of y to s
   942  		if sb == &none {
   943  			sb = s.insertBlockBefore(sb)
   944  		}
   945  		sb.offset = yb.offset
   946  		sb.bits = yb.bits
   947  		sb = s.next(sb)
   948  		yb = y.next(yb)
   949  	}
   950  
   951  	s.discardTail(sb)
   952  }
   953  
   954  // SubsetOf reports whether s ∖ x = ∅.
   955  func (s *Sparse) SubsetOf(x *Sparse) bool {
   956  	if s == x {
   957  		return true
   958  	}
   959  
   960  	sb := s.first()
   961  	xb := x.first()
   962  	for sb != &none {
   963  		switch {
   964  		case xb == &none || xb.offset > sb.offset:
   965  			return false
   966  		case xb.offset < sb.offset:
   967  			xb = x.next(xb)
   968  		default:
   969  			for i := range sb.bits {
   970  				if sb.bits[i]&^xb.bits[i] != 0 {
   971  					return false
   972  				}
   973  			}
   974  			sb = s.next(sb)
   975  			xb = x.next(xb)
   976  		}
   977  	}
   978  	return true
   979  }
   980  
   981  // Equals reports whether the sets s and t have the same elements.
   982  func (s *Sparse) Equals(t *Sparse) bool {
   983  	if s == t {
   984  		return true
   985  	}
   986  	sb := s.first()
   987  	tb := t.first()
   988  	for {
   989  		switch {
   990  		case sb == &none && tb == &none:
   991  			return true
   992  		case sb == &none || tb == &none:
   993  			return false
   994  		case sb.offset != tb.offset:
   995  			return false
   996  		case sb.bits != tb.bits:
   997  			return false
   998  		}
   999  
  1000  		sb = s.next(sb)
  1001  		tb = t.next(tb)
  1002  	}
  1003  }
  1004  
  1005  // String returns a human-readable description of the set s.
  1006  func (s *Sparse) String() string {
  1007  	var buf bytes.Buffer
  1008  	buf.WriteByte('{')
  1009  	s.forEach(func(x int) {
  1010  		if buf.Len() > 1 {
  1011  			buf.WriteByte(' ')
  1012  		}
  1013  		fmt.Fprintf(&buf, "%d", x)
  1014  	})
  1015  	buf.WriteByte('}')
  1016  	return buf.String()
  1017  }
  1018  
  1019  // BitString returns the set as a string of 1s and 0s denoting the sum
  1020  // of the i'th powers of 2, for each i in s.  A radix point, always
  1021  // preceded by a digit, appears if the sum is non-integral.
  1022  //
  1023  // Examples:
  1024  //              {}.BitString() =      "0"
  1025  //           {4,5}.BitString() = "110000"
  1026  //            {-3}.BitString() =      "0.001"
  1027  //      {-3,0,4,5}.BitString() = "110001.001"
  1028  //
  1029  func (s *Sparse) BitString() string {
  1030  	if s.IsEmpty() {
  1031  		return "0"
  1032  	}
  1033  
  1034  	min, max := s.Min(), s.Max()
  1035  	var nbytes int
  1036  	if max > 0 {
  1037  		nbytes = max
  1038  	}
  1039  	nbytes++ // zero bit
  1040  	radix := nbytes
  1041  	if min < 0 {
  1042  		nbytes += len(".") - min
  1043  	}
  1044  
  1045  	b := make([]byte, nbytes)
  1046  	for i := range b {
  1047  		b[i] = '0'
  1048  	}
  1049  	if radix < nbytes {
  1050  		b[radix] = '.'
  1051  	}
  1052  	s.forEach(func(x int) {
  1053  		if x >= 0 {
  1054  			x += len(".")
  1055  		}
  1056  		b[radix-x] = '1'
  1057  	})
  1058  	return string(b)
  1059  }
  1060  
  1061  // GoString returns a string showing the internal representation of
  1062  // the set s.
  1063  //
  1064  func (s *Sparse) GoString() string {
  1065  	var buf bytes.Buffer
  1066  	for b := s.first(); b != &none; b = s.next(b) {
  1067  		fmt.Fprintf(&buf, "block %p {offset=%d next=%p prev=%p",
  1068  			b, b.offset, b.next, b.prev)
  1069  		for _, w := range b.bits {
  1070  			fmt.Fprintf(&buf, " 0%016x", w)
  1071  		}
  1072  		fmt.Fprintf(&buf, "}\n")
  1073  	}
  1074  	return buf.String()
  1075  }
  1076  
  1077  // AppendTo returns the result of appending the elements of s to slice
  1078  // in order.
  1079  func (s *Sparse) AppendTo(slice []int) []int {
  1080  	s.forEach(func(x int) {
  1081  		slice = append(slice, x)
  1082  	})
  1083  	return slice
  1084  }
  1085  
  1086  // -- Testing/debugging ------------------------------------------------
  1087  
  1088  // check returns an error if the representation invariants of s are violated.
  1089  func (s *Sparse) check() error {
  1090  	s.init()
  1091  	if s.root.empty() {
  1092  		// An empty set must have only the root block with offset MaxInt.
  1093  		if s.root.next != &s.root {
  1094  			return fmt.Errorf("multiple blocks with empty root block")
  1095  		}
  1096  		if s.root.offset != MaxInt {
  1097  			return fmt.Errorf("empty set has offset %d, should be MaxInt", s.root.offset)
  1098  		}
  1099  		return nil
  1100  	}
  1101  	for b := s.first(); ; b = s.next(b) {
  1102  		if b.offset%bitsPerBlock != 0 {
  1103  			return fmt.Errorf("bad offset modulo: %d", b.offset)
  1104  		}
  1105  		if b.empty() {
  1106  			return fmt.Errorf("empty block")
  1107  		}
  1108  		if b.prev.next != b {
  1109  			return fmt.Errorf("bad prev.next link")
  1110  		}
  1111  		if b.next.prev != b {
  1112  			return fmt.Errorf("bad next.prev link")
  1113  		}
  1114  		if b.next == &s.root {
  1115  			break
  1116  		}
  1117  		if b.offset >= b.next.offset {
  1118  			return fmt.Errorf("bad offset order: b.offset=%d, b.next.offset=%d",
  1119  				b.offset, b.next.offset)
  1120  		}
  1121  	}
  1122  	return nil
  1123  }