toverl4.nim 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. discard """
  2. output: '''true'''
  3. """
  4. #bug #592
  5. type
  6. ElementKind = enum inner, leaf
  7. TElement[TKey, TData] = object
  8. case kind: ElementKind
  9. of inner:
  10. key: TKey
  11. left, right: ref TElement[Tkey, TData]
  12. of leaf:
  13. data: TData
  14. PElement[TKey, TData] = ref TElement[TKey, TData]
  15. proc newElement[Tkey, TData](other: PElement[TKey, TData]): PElement[Tkey, TData] =
  16. case other.kind:
  17. of inner:
  18. PElement[TKey, TData](kind: ElementKind.inner, key: other.key, left: other.left, right: other.right)
  19. of leaf:
  20. PElement[TKey, TData](kind: ElementKind.leaf, data: other.data)
  21. proc newElement[TKey, TData](key: TKey, left: PElement[TKey, TData] = nil, right: PElement[TKey, TData] = nil) : PElement[TKey, TData] =
  22. PElement[TKey, TData](kind: ElementKind.inner, key: key, left: left, right: right)
  23. proc newElement[Tkey, TData](key: Tkey, data: TData) : PElement[Tkey, TData] =
  24. PElement[TKey, TData](kind: ElementKind.leaf, data: data)
  25. proc find*[TKey, TData](root: PElement[TKey, TData], key: TKey): TData {.raises: [EInvalidKey].} =
  26. if root.left == nil:
  27. raise newException(EInvalidKey, "key does not exist: " & key)
  28. var tmp_element = addr(root)
  29. while tmp_element.kind == inner and tmp_element.right != nil:
  30. tmp_element = if tmp_element.key > key:
  31. addr(tmp_element.left)
  32. else:
  33. addr(tmp_element.right)
  34. if tmp_element.key == key:
  35. return tmp_element.left.data
  36. else:
  37. raise newException(EInvalidKey, "key does not exist: " & key)
  38. proc add*[TKey, TData](root: var PElement[TKey, TData], key: TKey, data: TData) : bool =
  39. if root.left == nil:
  40. root.key = key
  41. root.left = newElement[TKey, TData](key, data)
  42. return true
  43. var tmp_element = addr(root)
  44. while tmp_element.kind == ElementKind.inner and tmp_element.right != nil:
  45. tmp_element = if tmp_element.key > key:
  46. addr(tmp_element.left)
  47. else:
  48. addr(tmp_element.right)
  49. if tmp_element.key == key:
  50. return false
  51. var old_element = newElement[TKey, TData](tmp_element[])
  52. var new_element = newElement[TKey, TData](key, data)
  53. tmp_element[] = if tmp_element.key < key:
  54. newElement(key, old_element, new_element)
  55. else:
  56. newElement(tmp_element.key, new_element, old_element)
  57. return true
  58. var tree = PElement[int, int](kind: ElementKind.inner, key: 0, left: nil, right: nil)
  59. let result = add(tree, 1, 1)
  60. echo(result)