# This is a correct but poor implementation of quicksort found on the web (in
# more than one place).
# Comments (except these a the very beginning of the file) are from the
# original author (don't know who it is).
# DO NOT USE unless you modify it to make it good!
#
# To see poor behavior:
# Try 1) already sorted list of 10000 numbers
#            >>> l = list(range(10000))
#            >>> quicksort(l, 0, 9999)
#       2) list of 10000 identical numbers
#           >>> l = 10000 * [0]
#           >>> quicksort(l,0,9999)
# A good quicksort should handle such situations with no trouble at all.
#
# The problem is due to the very first line of partition:
#   pivot = list[end]
###############################################################################

import random
def partition(list, start, end):
    pivot = list[end]                          # Partition around the last value
    bottom = start-1                           # Start outside the area to be partitioned
    top = end                                  # Ditto

    done = 0
    while not done:                            # Until all elements are partitioned...
        while not done:                        # Until we find an out of place element...
            bottom = bottom+1                  # ... move the bottom up.

            if bottom == top:                  # If we hit the top...
                done = 1                       # ... we are done.
                break

            if list[bottom] > pivot:           # Is the bottom out of place?
                list[top] = list[bottom]       # Then put it at the top...
                break                          # ... and start searching from the top.

        while not done:                        # Until we find an out of place element...
            top = top-1                        # ... move the top down.
            
            if top == bottom:                  # If we hit the bottom...
                done = 1                       # ... we are done.
                break

            if list[top] < pivot:              # Is the top out of place?
                list[bottom] = list[top]       # Then put it at the bottom...
                break                          # ...and start searching from the bottom.

    list[top] = pivot                          # Put the pivot in its place.

    return top                                 # Return the split point


def quicksort(list, start, end):
    if start < end:                            # If there are two or more elements...
        split = partition(list, start, end)    # ... partition the sublist...
        quicksort(list, start, split-1)        # ... and sort both halves.
        quicksort(list, split+1, end)
    else:
        return
