





'''simple docstring'''




from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available


lowercase__   :				Union[str, Any]      =   {
    '''configuration_megatron_bert''': ['''MEGATRON_BERT_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''MegatronBertConfig'''],
}

try:
  if not is_torch_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  lowercase__   :				int      =   [
      '''MEGATRON_BERT_PRETRAINED_MODEL_ARCHIVE_LIST''',
      '''MegatronBertForCausalLM''',
      '''MegatronBertForMaskedLM''',
      '''MegatronBertForMultipleChoice''',
      '''MegatronBertForNextSentencePrediction''',
      '''MegatronBertForPreTraining''',
      '''MegatronBertForQuestionAnswering''',
      '''MegatronBertForSequenceClassification''',
      '''MegatronBertForTokenClassification''',
      '''MegatronBertModel''',
      '''MegatronBertPreTrainedModel''',
  ]

if TYPE_CHECKING:
  from .configuration_megatron_bert import MEGATRON_BERT_PRETRAINED_CONFIG_ARCHIVE_MAP, MegatronBertConfig

  try:
    if not is_torch_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_megatron_bert import (
        MEGATRON_BERT_PRETRAINED_MODEL_ARCHIVE_LIST,
        MegatronBertForCausalLM,
        MegatronBertForMaskedLM,
        MegatronBertForMultipleChoice,
        MegatronBertForNextSentencePrediction,
        MegatronBertForPreTraining,
        MegatronBertForQuestionAnswering,
        MegatronBertForSequenceClassification,
        MegatronBertForTokenClassification,
        MegatronBertModel,
        MegatronBertPreTrainedModel,
    )

else:
  import sys

  lowercase__   :				Tuple      =   _LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)






'''simple docstring'''




from collections.abc import Iterable
from typing import Any


class 			SCREAMING_SNAKE_CASE   :


     def __init__(						self						,     _UpperCAmelCase = None):

          '''simple docstring'''






          __A						:			str								=	value
          __A						:			Node | None								=	None  # Added in order to delete a node easier
          __A						:			Node | None								=	None
          __A						:			Node | None								=	None


     def __repr__(						self):

          '''simple docstring'''






          from pprint import pformat

          if self.left is None and self.right is None:
               return str(self.value)
          return pformat({F'{self.value}': (self.left, self.right)}						,     indent=1)




class 			SCREAMING_SNAKE_CASE   :


     def __init__(						self						,     _UpperCAmelCase = None):

          '''simple docstring'''






          __A						:			int								=	root


     def __str__(						self):

          '''simple docstring'''






          return str(self.root)


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase						,     _UpperCAmelCase):

          '''simple docstring'''






          if new_children is not None:  # reset its kids
               __A						:			Optional[int]								=	node.parent
          if node.parent is not None:  # reset its parent
               if self.is_right(_UpperCAmelCase):  # If it is the right children
                    __A						:			int								=	new_children
               else:
                    __A						:			Union[str, Any]								=	new_children
          else:
               __A						:			Tuple								=	new_children


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase):

          '''simple docstring'''






          if node.parent and node.parent.right:
               return node == node.parent.right
          return False


     def 							SCREAMING_SNAKE_CASE  (						self):

          '''simple docstring'''






          return self.root is None


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase):

          '''simple docstring'''






          __A						:			Dict								=	Node(_UpperCAmelCase)  # create a new Node
          if self.empty():  # if Tree is empty
               __A						:			Union[str, Any]								=	new_node  # set its root
          else:  # Tree is not empty
               __A						:			Dict								=	self.root  # from root
               if parent_node is None:
                    return
               while True:  # While we don't get to a leaf
                    if value < parent_node.value:  # We go left
                         if parent_node.left is None:
                              __A						:			Tuple								=	new_node  # We insert the new node in a leaf
                              break
                         else:
                              __A						:			str								=	parent_node.left
                    else:
                         if parent_node.right is None:
                              __A						:			List[str]								=	new_node
                              break
                         else:
                              __A						:			int								=	parent_node.right
               __A						:			int								=	parent_node


     def 							SCREAMING_SNAKE_CASE  (						self						,     *_UpperCAmelCase):

          '''simple docstring'''






          for value in values:
               self.__insert(_UpperCAmelCase)


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase):

          '''simple docstring'''






          if self.empty():
               raise IndexError('Warning: Tree is empty! please use another.')
          else:
               __A						:			Any								=	self.root
               # use lazy evaluation here to avoid NoneType Attribute error
               while node is not None and node.value is not value:
                    __A						:			List[Any]								=	node.left if value < node.value else node.right
               return node


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase = None):

          '''simple docstring'''






          if node is None:
               if self.root is None:
                    return None
               __A						:			str								=	self.root

          if not self.empty():
               while node.right is not None:
                    __A						:			Dict								=	node.right
          return node


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase = None):

          '''simple docstring'''






          if node is None:
               __A						:			Optional[Any]								=	self.root
          if self.root is None:
               return None
          if not self.empty():
               __A						:			Optional[int]								=	self.root
               while node.left is not None:
                    __A						:			Tuple								=	node.left
          return node


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase):

          '''simple docstring'''






          __A						:			Optional[Any]								=	self.search(_UpperCAmelCase)  # Look for the node with that label
          if node is not None:
               if node.left is None and node.right is None:  # If it has no children
                    self.__reassign_nodes(_UpperCAmelCase						,     _UpperCAmelCase)
               elif node.left is None:  # Has only right children
                    self.__reassign_nodes(_UpperCAmelCase						,     node.right)
               elif node.right is None:  # Has only left children
                    self.__reassign_nodes(_UpperCAmelCase						,     node.left)
               else:
                    __A						:			str								=	self.get_max(
                        node.left)  # Gets the max value of the left branch
                    self.remove(tmp_node.value)  # type: ignore
                    __A						:			List[Any]								=	(
                        tmp_node.value  # type: ignore
                    )  # Assigns the value to the node to delete and keep tree structure


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase):

          '''simple docstring'''






          if node is not None:
               yield node  # Preorder Traversal
               yield from self.preorder_traverse(node.left)
               yield from self.preorder_traverse(node.right)


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase=None):

          '''simple docstring'''






          if traversal_function is None:
               return self.preorder_traverse(self.root)
          else:
               return traversal_function(self.root)


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase						,     _UpperCAmelCase):

          '''simple docstring'''






          if node:
               self.inorder(_UpperCAmelCase						,     node.left)
               arr.append(node.value)
               self.inorder(_UpperCAmelCase						,     node.right)


     def 							SCREAMING_SNAKE_CASE  (						self						,     _UpperCAmelCase						,     _UpperCAmelCase):

          '''simple docstring'''






          __A						:			list[int]								=	[]
          self.inorder(_UpperCAmelCase						,     _UpperCAmelCase)  # append all values to list using inorder traversal
          return arr[k - 1]






def 	_lowerCAmelCase      (  __snake_case  :			Node | None      )					->					list[Node]:
     __A						:			Tuple								=	[]
     if curr_node is not None:
          __A						:			Optional[Any]								=	postorder(curr_node.left      ) + postorder(curr_node.right      ) + [curr_node]
     return node_list






def 	_lowerCAmelCase      (  )					->					None:
     __A						:			Optional[int]								=	(8, 3, 6, 1, 10, 14, 13, 4, 7)
     __A						:			str								=	BinarySearchTree()
     for i in testlist:
          t.insert(__snake_case      )

     # Prints all the elements of the list in order traversal
     print(__snake_case      )

     if t.search(6      ) is not None:
          print('The value 6 exists'      )
     else:
          print('The value 6 doesn\'t exist'      )

     if t.search(-1      ) is not None:
          print('The value -1 exists'      )
     else:
          print('The value -1 doesn\'t exist'      )

     if not t.empty():
          print('Max Value: '			,							t.get_max().value      )  # type: ignore
          print('Min Value: '			,							t.get_min().value      )  # type: ignore

     for i in testlist:
          t.remove(__snake_case      )
          print(__snake_case      )


if __name__ == "__main__":
  import doctest

  doctest.testmod(verbose=True)