bitsets.nim 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # this unit handles Nim sets; it implements bit sets
  10. # the code here should be reused in the Nim standard library
  11. type
  12. ElemType = byte
  13. TBitSet* = seq[ElemType] # we use byte here to avoid issues with
  14. # cross-compiling; uint would be more efficient
  15. # however
  16. const
  17. ElemSize* = 8
  18. One = ElemType(1)
  19. Zero = ElemType(0)
  20. template modElemSize(arg: untyped): untyped = arg and 7
  21. template divElemSize(arg: untyped): untyped = arg shr 3
  22. proc bitSetInit*(b: var TBitSet, length: int)
  23. proc bitSetUnion*(x: var TBitSet, y: TBitSet)
  24. proc bitSetDiff*(x: var TBitSet, y: TBitSet)
  25. proc bitSetSymDiff*(x: var TBitSet, y: TBitSet)
  26. proc bitSetIntersect*(x: var TBitSet, y: TBitSet)
  27. proc bitSetIncl*(x: var TBitSet, elem: BiggestInt)
  28. proc bitSetExcl*(x: var TBitSet, elem: BiggestInt)
  29. proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
  30. proc bitSetEquals*(x, y: TBitSet): bool
  31. proc bitSetContains*(x, y: TBitSet): bool
  32. proc bitSetCard*(x: TBitSet): BiggestInt
  33. # implementation
  34. proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
  35. result = (x[int(e.divElemSize)] and (One shl e.modElemSize)) != Zero
  36. proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
  37. assert(elem >= 0)
  38. x[int(elem.divElemSize)] = x[int(elem.divElemSize)] or
  39. (One shl elem.modElemSize)
  40. proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
  41. x[int(elem.divElemSize)] = x[int(elem.divElemSize)] and
  42. not(One shl elem.modElemSize)
  43. proc bitSetInit(b: var TBitSet, length: int) =
  44. newSeq(b, length)
  45. proc bitSetUnion(x: var TBitSet, y: TBitSet) =
  46. for i in 0 .. high(x): x[i] = x[i] or y[i]
  47. proc bitSetDiff(x: var TBitSet, y: TBitSet) =
  48. for i in 0 .. high(x): x[i] = x[i] and not y[i]
  49. proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
  50. for i in 0 .. high(x): x[i] = x[i] xor y[i]
  51. proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
  52. for i in 0 .. high(x): x[i] = x[i] and y[i]
  53. proc bitSetEquals(x, y: TBitSet): bool =
  54. for i in 0 .. high(x):
  55. if x[i] != y[i]:
  56. return false
  57. result = true
  58. proc bitSetContains(x, y: TBitSet): bool =
  59. for i in 0 .. high(x):
  60. if (x[i] and not y[i]) != Zero:
  61. return false
  62. result = true
  63. # Number of set bits for all values of int8
  64. const populationCount: array[uint8, uint8] = block:
  65. var arr: array[uint8, uint8]
  66. proc countSetBits(x: uint8): uint8 =
  67. return
  68. ( x and 0b00000001'u8) +
  69. ((x and 0b00000010'u8) shr 1) +
  70. ((x and 0b00000100'u8) shr 2) +
  71. ((x and 0b00001000'u8) shr 3) +
  72. ((x and 0b00010000'u8) shr 4) +
  73. ((x and 0b00100000'u8) shr 5) +
  74. ((x and 0b01000000'u8) shr 6) +
  75. ((x and 0b10000000'u8) shr 7)
  76. for it in low(uint8)..high(uint8):
  77. arr[it] = countSetBits(cast[uint8](it))
  78. arr
  79. proc bitSetCard(x: TBitSet): BiggestInt =
  80. for it in x:
  81. result.inc int(populationCount[it])