# Quicksort pairs
# eg. input of the form [ 30, 1, 90, 2, 70, 3, 50, 4]
# outputs [ 30, 1, 50, 4, 70, 3, 90, 2 ]
#
# Note: this can be used as a generalized sorting algorithm:
# map every object to [ key, ref ] where `ref` is the index
# in memory to all of the properties and `key` is the key to
# sort by


def kall():
    argcount = ~calldatasize() / 64
    if argcount == 1:
        return([~calldataload(1), ~calldataload(33)], 2)

    args = array(argcount * 2)
    ~calldatacopy(args, 1, argcount * 64)
    low = array(argcount * 2)
    lsz = 0
    high = array(argcount * 2)
    hsz = 0
    i = 2
    while i < argcount * 2:
        if args[i] < args[0]:
            low[lsz] = args[i]
            low[lsz + 1] = args[i + 1]
            lsz += 2
        else:
            high[hsz] = args[i]
            high[hsz + 1] = args[i + 1]
            hsz += 2
        i = i + 2
    low = self.kall(data=low, datasz=lsz, outsz=lsz)
    high = self.kall(data=high, datasz=hsz, outsz=hsz)
    o = array(argcount * 2)
    i = 0
    while i < lsz:
        o[i] = low[i]
        i += 1
    o[lsz] = args[0]
    o[lsz + 1] = args[1]
    j = 0
    while j < hsz:
        o[lsz + 2 + j] = high[j]
        j += 1
    return(o, argcount * 2)
