towned_binary_tree.nim 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. discard """
  2. cmd: '''nim c -d:nimAllocStats --gc:arc $file'''
  3. output: '''31665
  4. (allocCount: 33334, deallocCount: 33334)'''
  5. """
  6. # bug #11053
  7. import random
  8. type Node = ref object
  9. x, y: int32
  10. left, right: owned Node
  11. proc newNode(x: int32): owned Node =
  12. result = Node(x: x, y: rand(high int32).int32)
  13. proc merge(lower, greater: owned Node): owned Node =
  14. if lower.isNil:
  15. result = greater
  16. elif greater.isNil:
  17. result = lower
  18. elif lower.y < greater.y:
  19. lower.right = merge(lower.right, greater)
  20. result = lower
  21. else:
  22. greater.left = merge(lower, greater.left)
  23. result = greater
  24. proc splitBinary(orig: owned Node, value: int32): (owned Node, owned Node) =
  25. if orig.isNil:
  26. result = (nil, nil)
  27. elif orig.x < value:
  28. let splitPair = splitBinary(orig.right, value)
  29. orig.right = splitPair[0]
  30. result = (orig, splitPair[1])
  31. else:
  32. let splitPair = splitBinary(orig.left, value)
  33. orig.left = splitPair[1]
  34. result = (splitPair[0], orig)
  35. proc merge3(lower, equal, greater: owned Node): owned Node =
  36. merge(merge(lower, equal), greater)
  37. proc split(orig: owned Node, value: int32): tuple[lower, equal, greater: owned Node] =
  38. let
  39. (lower, equalGreater) = splitBinary(orig, value)
  40. (equal, greater) = splitBinary(equalGreater, value + 1)
  41. result = (lower, equal, greater)
  42. type Tree = object
  43. root: owned Node
  44. proc hasValue(self: var Tree, x: int32): bool =
  45. let splited = split(move self.root, x)
  46. result = not splited.equal.isNil
  47. self.root = merge3(splited.lower, splited.equal, splited.greater)
  48. proc insert(self: var Tree, x: int32) =
  49. var splited = split(move self.root, x)
  50. if splited.equal.isNil:
  51. splited.equal = newNode(x)
  52. self.root = merge3(splited.lower, splited.equal, splited.greater)
  53. proc erase(self: var Tree, x: int32) =
  54. let splited = split(move self.root, x)
  55. self.root = merge(splited.lower, splited.greater)
  56. proc main() =
  57. var
  58. tree = Tree()
  59. cur = 5'i32
  60. res = 0
  61. for i in 1 ..< 100000:
  62. let a = i mod 3
  63. cur = (cur * 57 + 43) mod 10007
  64. case a:
  65. of 0:
  66. tree.insert(cur)
  67. of 1:
  68. tree.erase(cur)
  69. of 2:
  70. if tree.hasValue(cur):
  71. res += 1
  72. else:
  73. discard
  74. echo res
  75. dumpAllocStats:
  76. main()