type
ElementKind = enum inner, leaf
TElement[TKey, TData] = object
case kind: ElementKind
of inner:
key: TKey
left, right: ref TElement[Tkey, TData]
of leaf:
data: TData
PElement[TKey, TData] = ref TElement[TKey, TData]
proc newElement[Tkey, TData](other: PElement[TKey, TData]): PElement[Tkey, TData] =
case other.kind:
of inner:
PElement[TKey, TData](kind: ElementKind.inner, key: other.key, left: other.left, right: other.right)
of leaf:
PElement[TKey, TData](kind: ElementKind.leaf, data: other.data)
proc newElement[TKey, TData](key: TKey, left: PElement[TKey, TData] = nil, right: PElement[TKey, TData] = nil) : PElement[TKey, TData] =
PElement[TKey, TData](kind: ElementKind.inner, key: key, left: left, right: right)
proc newElement[Tkey, TData](key: Tkey, data: TData) : PElement[Tkey, TData] =
PElement[TKey, TData](kind: ElementKind.leaf, data: data)
proc find*[TKey, TData](root: PElement[TKey, TData], key: TKey): TData {.raises: [EInvalidKey].} =
if root.left == nil:
raise newException
(EInvalidKey
, "key does not exist: " & key
)
var tmp_element = addr(root)
while tmp_element.kind == inner and tmp_element.right != nil:
tmp_element = if tmp_element.key > key:
tmp_element.left
else:
tmp_element.right
if tmp_element.key == key:
return tmp_element.left.data
else:
raise newException
(EInvalidKey
, "key does not exist: " & key
)
proc add*[TKey, TData](root: var PElement[TKey, TData], key: TKey, data: TData) : bool =
if root.left == nil:
root.key = key
root.left = newElement[TKey, TData](key, data)
return true
var tmp_element = addr(root)
while tmp_element.kind == ElementKind.inner and tmp_element.right != nil:
tmp_element = if tmp_element.key > key:
addr(tmp_element.left)
else:
addr(tmp_element.right)
if tmp_element.key == key:
return false
var old_element = newElement[TKey, TData](tmp_element)
var new_element = newElement[TKey, TData](key, data)
tmp_element[] = if tmp_element.key < key:
newElement(key, old_element, new_element)
else:
newElement(tmp_element.key, new_element, old_element)
true
var tree = PElement[int, int](kind: ElementKind.inner, key: 0, left: nil, right: nil)
add(tree, 1, 1)
dHlwZQogIEVsZW1lbnRLaW5kID0gZW51bSBpbm5lciwgbGVhZgogIFRFbGVtZW50W1RLZXksIFREYXRhXSA9IG9iamVjdAogICAgY2FzZSBraW5kOiBFbGVtZW50S2luZAogICAgb2YgaW5uZXI6CiAgICAgIGtleTogVEtleQogICAgICBsZWZ0LCByaWdodDogcmVmIFRFbGVtZW50W1RrZXksIFREYXRhXQogICAgb2YgbGVhZjoKICAgICAgZGF0YTogVERhdGEKICBQRWxlbWVudFtUS2V5LCBURGF0YV0gPSByZWYgVEVsZW1lbnRbVEtleSwgVERhdGFdCgpwcm9jIG5ld0VsZW1lbnRbVGtleSwgVERhdGFdKG90aGVyOiBQRWxlbWVudFtUS2V5LCBURGF0YV0pOiBQRWxlbWVudFtUa2V5LCBURGF0YV0gPQogIGNhc2Ugb3RoZXIua2luZDoKICBvZiBpbm5lcjoKICAgIFBFbGVtZW50W1RLZXksIFREYXRhXShraW5kOiBFbGVtZW50S2luZC5pbm5lciwga2V5OiBvdGhlci5rZXksIGxlZnQ6IG90aGVyLmxlZnQsIHJpZ2h0OiBvdGhlci5yaWdodCkKICBvZiBsZWFmOgogICAgUEVsZW1lbnRbVEtleSwgVERhdGFdKGtpbmQ6IEVsZW1lbnRLaW5kLmxlYWYsIGRhdGE6IG90aGVyLmRhdGEpCgpwcm9jIG5ld0VsZW1lbnRbVEtleSwgVERhdGFdKGtleTogVEtleSwgbGVmdDogUEVsZW1lbnRbVEtleSwgVERhdGFdID0gbmlsLCByaWdodDogUEVsZW1lbnRbVEtleSwgVERhdGFdID0gbmlsKSA6IFBFbGVtZW50W1RLZXksIFREYXRhXSA9CiAgUEVsZW1lbnRbVEtleSwgVERhdGFdKGtpbmQ6IEVsZW1lbnRLaW5kLmlubmVyLCBrZXk6IGtleSwgbGVmdDogbGVmdCwgcmlnaHQ6IHJpZ2h0KQoKcHJvYyBuZXdFbGVtZW50W1RrZXksIFREYXRhXShrZXk6IFRrZXksIGRhdGE6IFREYXRhKSA6IFBFbGVtZW50W1RrZXksIFREYXRhXSA9CiAgUEVsZW1lbnRbVEtleSwgVERhdGFdKGtpbmQ6IEVsZW1lbnRLaW5kLmxlYWYsIGRhdGE6IGRhdGEpCgpwcm9jIGZpbmQqW1RLZXksIFREYXRhXShyb290OiBQRWxlbWVudFtUS2V5LCBURGF0YV0sIGtleTogVEtleSk6IFREYXRhIHsucmFpc2VzOiBbRUludmFsaWRLZXldLn0gPQogIGlmIHJvb3QubGVmdCA9PSBuaWw6CiAgICByYWlzZSBuZXdFeGNlcHRpb24oRUludmFsaWRLZXksICJrZXkgZG9lcyBub3QgZXhpc3Q6ICIgJiBrZXkpCgogIHZhciB0bXBfZWxlbWVudCA9IGFkZHIocm9vdCkKCiAgd2hpbGUgdG1wX2VsZW1lbnQua2luZCA9PSBpbm5lciBhbmQgdG1wX2VsZW1lbnQucmlnaHQgIT0gbmlsOgogICAgdG1wX2VsZW1lbnQgPSBpZiB0bXBfZWxlbWVudC5rZXkgPiBrZXk6CiAgICAgICAgICAgICAgICAgICAgdG1wX2VsZW1lbnQubGVmdCAKICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICB0bXBfZWxlbWVudC5yaWdodAogICAKICBpZiB0bXBfZWxlbWVudC5rZXkgPT0ga2V5OgogICAgcmV0dXJuIHRtcF9lbGVtZW50LmxlZnQuZGF0YQogIGVsc2U6CiAgICByYWlzZSBuZXdFeGNlcHRpb24oRUludmFsaWRLZXksICJrZXkgZG9lcyBub3QgZXhpc3Q6ICIgJiBrZXkpCgpwcm9jIGFkZCpbVEtleSwgVERhdGFdKHJvb3Q6IHZhciBQRWxlbWVudFtUS2V5LCBURGF0YV0sIGtleTogVEtleSwgZGF0YTogVERhdGEpIDogYm9vbCA9CiAgaWYgcm9vdC5sZWZ0ID09IG5pbDoKICAgIHJvb3Qua2V5ID0ga2V5CiAgICByb290LmxlZnQgPSBuZXdFbGVtZW50W1RLZXksIFREYXRhXShrZXksIGRhdGEpCiAgICByZXR1cm4gdHJ1ZQoKICB2YXIgdG1wX2VsZW1lbnQgPSBhZGRyKHJvb3QpCgogIHdoaWxlIHRtcF9lbGVtZW50LmtpbmQgPT0gRWxlbWVudEtpbmQuaW5uZXIgYW5kIHRtcF9lbGVtZW50LnJpZ2h0ICE9IG5pbDoKICAgIHRtcF9lbGVtZW50ID0gaWYgdG1wX2VsZW1lbnQua2V5ID4ga2V5OgogICAgICAgICAgICAgICAgICAgIGFkZHIodG1wX2VsZW1lbnQubGVmdCkKICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBhZGRyKHRtcF9lbGVtZW50LnJpZ2h0KQoKICBpZiB0bXBfZWxlbWVudC5rZXkgPT0ga2V5OgogICAgcmV0dXJuIGZhbHNlCgogIHZhciBvbGRfZWxlbWVudCA9IG5ld0VsZW1lbnRbVEtleSwgVERhdGFdKHRtcF9lbGVtZW50KQogIHZhciBuZXdfZWxlbWVudCA9IG5ld0VsZW1lbnRbVEtleSwgVERhdGFdKGtleSwgZGF0YSkKCiAgdG1wX2VsZW1lbnRbXSA9IGlmIHRtcF9lbGVtZW50LmtleSA8IGtleToKICAgICAgICAgICAgICAgICAgICBuZXdFbGVtZW50KGtleSwgb2xkX2VsZW1lbnQsIG5ld19lbGVtZW50KQogICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIG5ld0VsZW1lbnQodG1wX2VsZW1lbnQua2V5LCBuZXdfZWxlbWVudCwgb2xkX2VsZW1lbnQpCgogIHRydWUKICAKdmFyIHRyZWUgPSBQRWxlbWVudFtpbnQsIGludF0oa2luZDogRWxlbWVudEtpbmQuaW5uZXIsIGtleTogMCwgbGVmdDogbmlsLCByaWdodDogbmlsKQoKYWRkKHRyZWUsIDEsIDEp