# We acted this out in class with 16 cards.  A call to merge_sort(L)
# is analogous to giving a person cards to sort.  After they divided
# the pile of cards into two piles, they gave each pile to another student
# to sort.  This is analogous to the two recursive calls to merge_sort
# in the algorithm.  Of course, each of those helper students did the exact
# same thing, following the algorithm, until some students ended up with
# exactly one card.  This was when we realized the importance of having
# that case covered in the algorithm.

def merge_sort(L):
    """
    (list of comparables) -> list of comparables
    
    Return a a new list, sorted in non-descending order containing 
    the elements of L.
    
    >>> L1 = [5, 1, 2, 18, 0]
    >>> L2 = merge_sort(L1)
    >>> L2
    [0, 1, 2, 5, 18]
    """
    
    # Algorithm:
    
    # If the list has length only 1 (or length 0):
    #     return L -- it's already sorted
    # else:
    #     Divide the list into two halves, L1 and L2
    #     merge_sort(L1)
    #     merge_sort(L2)
    #     return what you get from merging L1 and L2 together