bitsets.nim 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. TBitSet* = seq[int8] # we use byte here to avoid issues with
  13. # cross-compiling; uint would be more efficient
  14. # however
  15. const
  16. ElemSize* = sizeof(int8) * 8
  17. proc bitSetInit*(b: var TBitSet, length: int)
  18. proc bitSetUnion*(x: var TBitSet, y: TBitSet)
  19. proc bitSetDiff*(x: var TBitSet, y: TBitSet)
  20. proc bitSetSymDiff*(x: var TBitSet, y: TBitSet)
  21. proc bitSetIntersect*(x: var TBitSet, y: TBitSet)
  22. proc bitSetIncl*(x: var TBitSet, elem: BiggestInt)
  23. proc bitSetExcl*(x: var TBitSet, elem: BiggestInt)
  24. proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
  25. proc bitSetEquals*(x, y: TBitSet): bool
  26. proc bitSetContains*(x, y: TBitSet): bool
  27. proc bitSetCard*(x: TBitSet): BiggestInt
  28. # implementation
  29. proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
  30. result = (x[int(e div ElemSize)] and toU8(int(1 shl (e mod ElemSize)))) !=
  31. toU8(0)
  32. proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
  33. assert(elem >= 0)
  34. x[int(elem div ElemSize)] = x[int(elem div ElemSize)] or
  35. toU8(int(1 shl (elem mod ElemSize)))
  36. proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
  37. x[int(elem div ElemSize)] = x[int(elem div ElemSize)] and
  38. not toU8(int(1 shl (elem mod ElemSize)))
  39. proc bitSetInit(b: var TBitSet, length: int) =
  40. newSeq(b, length)
  41. proc bitSetUnion(x: var TBitSet, y: TBitSet) =
  42. for i in countup(0, high(x)): x[i] = x[i] or y[i]
  43. proc bitSetDiff(x: var TBitSet, y: TBitSet) =
  44. for i in countup(0, high(x)): x[i] = x[i] and not y[i]
  45. proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
  46. for i in countup(0, high(x)): x[i] = x[i] xor y[i]
  47. proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
  48. for i in countup(0, high(x)): x[i] = x[i] and y[i]
  49. proc bitSetEquals(x, y: TBitSet): bool =
  50. for i in countup(0, high(x)):
  51. if x[i] != y[i]:
  52. return false
  53. result = true
  54. proc bitSetContains(x, y: TBitSet): bool =
  55. for i in countup(0, high(x)):
  56. if (x[i] and not y[i]) != int8(0):
  57. return false
  58. result = true
  59. # Number of set bits for all values of int8
  60. const populationCount: array[low(int8)..high(int8), int8] = block:
  61. var arr: array[low(int8)..high(int8), int8]
  62. proc countSetBits(x: int8): int8 =
  63. return
  64. ( x and 0b00000001'i8) +
  65. ((x and 0b00000010'i8) shr 1) +
  66. ((x and 0b00000100'i8) shr 2) +
  67. ((x and 0b00001000'i8) shr 3) +
  68. ((x and 0b00010000'i8) shr 4) +
  69. ((x and 0b00100000'i8) shr 5) +
  70. ((x and 0b01000000'i8) shr 6) +
  71. ((x and 0b10000000'i8) shr 7)
  72. for it in low(int8)..high(int8):
  73. arr[it] = countSetBits(it)
  74. arr
  75. proc bitSetCard(x: TBitSet): BiggestInt =
  76. for it in x:
  77. result.inc populationCount[it]