def affiche_arbre(arbre) -> None:
    print(chaine_representation_arbre(arbre))

def chaine_representation_arbre(arbre) -> str:
    """Return the pretty-print string for the binary tree.

    :return: Pretty-print string.
    :rtype: str

    **Example**:

    .. doctest::

        >>> from binarytree import Noeud
        >>>
        >>> root = Noeud(1)
        >>> root.fils_gauche = Noeud(2)
        >>> root.fils_droit = Noeud(3)
        >>> root.fils_gauche.fils_droit = Noeud(4)
        >>>
        >>> print(root)
        <BLANKLINE>
          __1
         /   \\
        2     3
         \\
          4
        <BLANKLINE>

    .. note::
        To include level-order_ indexes in the output string, use
        :func:`binarytree.Noeud.pprint` instead.

    .. _level-order:
        https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search
    """
    lines = _build_tree_string(arbre, 0, False, "-")[0]
    return "\n" + "\n".join((line.rstrip() for line in lines))

def _build_tree_string(root, curr_index: int,
                        include_index: bool = False,
                delimiter: str = "-"):
    """Recursively walk down the binary tree and build a pretty-print string.

    In each recursive call, a "box" of characters visually representing the
    current (sub)tree is constructed line by line. Each line is padded with
    whitespaces to ensure all lines in the box have the same length. Then the
    box, its width, and start-end positions of its root Noeud value repr string
    (required for drawing branches) are sent up to the parent call. The parent
    call then combines its left and right sub-boxes to build a larger box etc.

    :param root: Root Noeud of the binary tree.
    :type root: binarytree.Noeud | None
    :param curr_index: Level-order_ index of the current Noeud (root Noeud is 0).
    :type curr_index: int
    :param include_index: If set to True, include the level-order_ Noeud indexes using
        the following format: ``{index}{delimiter}{value}`` (default: False).
    :type include_index: bool
    :param delimiter: Delimiter character between the Noeud index and the Noeud
        value (default: '-').
    :type delimiter:
    :return: Box of characters visually representing the current subtree, width
        of the box, and start-end positions of the repr string of the new root
        Noeud value.
    :rtype: ([str], int, int, int)

    .. _Level-order:
        https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search
    """
    if root is None:
        return [], 0, 0, 0

    line1 = []
    line2 = []
    if include_index:
        Noeud_repr = "{}{}{}".format(curr_index, delimiter, root.valeur)
    else:
        Noeud_repr = str(root.valeur)

    new_root_width = gap_size = len(Noeud_repr)

    # Get the left and right sub-boxes, their widths, and root repr positions
    l_box, l_box_width, l_root_start, l_root_end = _build_tree_string(
        root.fils_gauche, 2 * curr_index + 1, include_index, delimiter
    )
    r_box, r_box_width, r_root_start, r_root_end = _build_tree_string(
        root.fils_droit, 2 * curr_index + 2, include_index, delimiter
    )

    # Draw the branch connecting the current root Noeud to the left sub-box
    # Pad the line with whitespaces where necessary
    if l_box_width > 0:
        l_root = (l_root_start + l_root_end) // 2 + 1
        line1.append(" " * (l_root + 1))
        line1.append("_" * (l_box_width - l_root))
        line2.append(" " * l_root + "/")
        line2.append(" " * (l_box_width - l_root))
        new_root_start = l_box_width + 1
        gap_size += 1
    else:
        new_root_start = 0

    # Draw the representation of the current root Noeud
    line1.append(Noeud_repr)
    line2.append(" " * new_root_width)

    # Draw the branch connecting the current root Noeud to the right sub-box
    # Pad the line with whitespaces where necessary
    if r_box_width > 0:
        r_root = (r_root_start + r_root_end) // 2
        line1.append("_" * r_root)
        line1.append(" " * (r_box_width - r_root + 1))
        line2.append(" " * r_root + "\\")
        line2.append(" " * (r_box_width - r_root))
        gap_size += 1
    new_root_end = new_root_start + new_root_width - 1

    # Combine the left and right sub-boxes with the branches drawn above
    gap = " " * gap_size
    new_box = ["".join(line1), "".join(line2)]
    for i in range(max(len(l_box), len(r_box))):
        l_line = l_box[i] if i < len(l_box) else " " * l_box_width
        r_line = r_box[i] if i < len(r_box) else " " * r_box_width
        new_box.append(l_line + gap + r_line)

    # Return the new box, its width and its root repr positions
    return new_box, len(new_box[0]), new_root_start, new_root_end
