def test_insertion_sort(seq):
    """Test insertion sort results equal build-in python sort results."""
    from insertion_sort import insertion_sort
    seq = list(seq)
    sorted_copy = sorted(seq)
    insertion_sort(seq)
    assert seq == sorted_copy
Example #2
0
def bucket_sort(item, begin, end, key=None):
    if key is None:
        key = lambda x: x[0] if isinstance(x, (
            list,
            tuple,
        )) else x
    size = end - begin + 1
    buckets = [None] * size
    i = begin

    while i <= end:
        if buckets[int(size * key(item[i]))] is None:
            buckets[int(size * key(item[i]))] = [item[i]]
        else:
            buckets[int(size * key(item[i]))].append(item[i])
        i += 1

    i = 0
    while i < size:
        if buckets[i] is not None:
            insertion_sort(buckets[i],
                           0,
                           len(buckets[i]) - 1,
                           condition=lambda a, b: key(a) <= key(b)
                           )  # equality must be check for stable sorting
        i += 1

    i = 0
    for bucket in buckets:
        if bucket is not None:
            for e in bucket:
                item[begin + i] = e
                i += 1
Example #3
0
def main():

    list = [12, 11, 13, 5, 6]
    insertion_sort(list)

    for i in range(len(list)):
        print("%d" % list[i])
def extract(buckets, array, order):
    '''
    Copy elements from buckets back to array.
    '''

    if order == 'asc':
        i = 0
        d = 1
    else:
        i = len(array) - 1
        d = -1

    for bucket in buckets:
        if not bucket:
            continue

        if len(bucket) > 1:
            # sort bucket first
            insertion_sort(bucket)
            for b in bucket:
                array[i] = b
                i += d
        else:
            # bucket only has one element
            array[i] = bucket[0]
            i += d
def bucket_sort(array, bucketSize=6):
    if len(array) == 0:
        return array

    # Determine minimum and maximum values
    minValue = array[0]
    maxValue = array[0]
    for i in range(1, len(array)):
        if array[i] < minValue:
            minValue = array[i]
        elif array[i] > maxValue:
            maxValue = array[i]

    # Initialize buckets
    bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1
    buckets = []
    for i in range(0, bucketCount):
        buckets.append([])

    # Distribute input array values into buckets
    for i in range(0, len(array)):
        buckets[math.floor(
            (array[i] - minValue) / bucketSize)].append(array[i])

    # Sort buckets and place back into input array
    array = []
    for i in range(0, len(buckets)):
        insertion_sort(buckets[i])
        for j in range(0, len(buckets[i])):
            array.append(buckets[i][j])

    return array
Example #6
0
def bucket_sort(arr):
    if len(arr) < 2:
        return arr
    # pick a number of buckets
    k = (1 + len(arr) // 2)
    # make list of buckets
    bucket_arr = [[] for n in range(k)]
    # find maximum
    max_value = arr[0]
    for i in range(len(arr)):
        if arr[i] > max_value:
            max_value = arr[i]
    # sort each element into a bucket
    for j in range(len(arr)):
        # each element goes into a bucket that is its fraction of the maximum
        bucket_number = math.floor((arr[j] / (max_value + 1) * k))
        bucket_arr[bucket_number].append(arr[j])

    for arr in bucket_arr:
        insertion_sort(arr)

    output = []
    for bucket in bucket_arr:
        output += bucket
    return output
def is_permutation(str1, str2):
    if type(str1) != t.StringType or type(str2) != t.StringType:
        raise TypeError("Both arguements must be string")

    str1 = str1.rstrip()
    str2 = str2.rstrip()

    if str1 == "" or str2 == "":
        raise ValueError("Both of the arguements must be non-emtpy")

    arr1 = [x for x in str1]
    arr2 = [y for y in str2]

    size1 = len(arr1)
    size2 = len(arr2)

    if size1 != size2:
        return False

    arr1 = i.insertion_sort(arr1, size1)
    arr2 = i.insertion_sort(arr2, size2)

    j = 0
    k = 0

    while j < size1:
        if arr1[j] != arr2[k]:
            return False

        j += 1
        k += 1

    return True
Example #8
0
def timsort(items):
    min_subsection_size = 32

    # Sort each subsection of size 32
    # (The real algorithm carefully chooses a subsection size for performance.)
    for i in range(0, len(items), min_subsection_size):
        insertion_sort(items, i,
                       min((i + min_subsection_size - 1),
                           len(items) - 1))

    # Move through the list of subsections and merge them using merge_sorted_lists
    # (Again, the real algorithm carefully chooses when to do this.)
    size = min_subsection_size
    while size < len(items):
        for start in range(0, len(items), size * 2):
            midpoint = start + size - 1
            end = min((start + size * 2 - 1),
                      (len(items) - 1))  # arithmetic to properly index

            # Merge using merge_sorted_lists
            merged_array = merge_sorted_lists(items[start:midpoint + 1],
                                              items[midpoint + 1:end + 1])

            items[start:start +
                  len(merged_array)] = merged_array  # Insert merged array
        size *= 2  # Double the size of the merged chunks each time until it reaches the whole list

    return items
Example #9
0
def test_alg(alg, size_array):
    """
    Tests
    """

    t_arrays = []

    # Create the random arrays
    for i in range(N_TESTS_ALG):
        a = [randint(-2**N_BITS, 2**N_BITS) for i in range(size_array)]
        t_arrays.append(a)

    # Insertion Sort
    if alg == INSERTION_SORT:
        print("INSERTION_SORT", end=",")
        print("N=%d" % (size_array))

        # Test N times to get a more precise average time
        for test in range(N_TESTS_ALG):
            A = list.copy(t_arrays[test])
            t1 = time()
            insertion_sort(A)
            t2 = time()
            print("T%d," % test, t2 - t1)

    elif alg == MERGE_SORT:
        print("MERGE_SORT", end=",")
        print("N=%d" % (size_array))

        # Test N times to get a more precise average time
        for test in range(N_TESTS_ALG):
            A = list.copy(t_arrays[test])
            t1 = time()
            merge_sort(A, 0, len(A) - 1)
            t2 = time()
            print("T%d," % test, t2 - t1)

    elif alg == RADIX_SORT:
        print("RADIX_SORT", end=",")
        print("N=%d" % (size_array))

        # Test N times to get a more precise average time
        for test in range(N_TESTS_ALG):
            A = list.copy(t_arrays[test])
            t1 = time()
            radix_sort(A)
            t2 = time()
            print("T%d," % test, t2 - t1)

    elif alg == BUCKET_SORT:
        print("BUCKET_SORT", end=",")
        print("N=%d" % (size_array))

        # Test N times to get a more precise average time
        for test in range(N_TESTS_ALG):
            A = list.copy(t_arrays[test])
            t1 = time()
            bucket_sort(A, len(A))
            t2 = time()
            print("T%d," % test, t2 - t1)
Example #10
0
def merge_ins_sort(array, partition=2):
    """
    Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make
    it faster in practice for small problem sizes on many machines.
    Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when
    subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are
    sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined.

    bottom to top version with number of sublists specified
    :param array:
    :param partition: number of sublists
    :return:
    """
    assert partition > 0
    n = len(array)
    sublist_length = math.ceil(n / partition)
    sublist_number = partition
    for i in range(sublist_number):
        left = sublist_length * i
        right = min(sublist_length * (i + 1) - 1, n - 1)
        insertion_sort(array, left, right)
    while sublist_number > 1:
        for i in range(0, sublist_number - 1, 2):
            merge_with_sentinel(array, sublist_length * i,
                                sublist_length * (i + 1) - 1,
                                min(sublist_length * (i + 2) - 1, n - 1))
        sublist_length *= 2
        sublist_number = math.ceil(sublist_number / 2)
Example #11
0
def quick_sort_three_ways(arr, l, r):
    if r - l <= 15:
        insertion_sort(arr)
        return
    lt, gt = partition_three_ways(arr, l, r)
    quick_sort_three_ways(arr, l, lt - 1)
    quick_sort_three_ways(arr, gt, r)
Example #12
0
def run_insertion_sort():
    rand_arr = utils.generate_random_array(101)
    rand_copy = list(rand_arr)
    rand_arr.sort()
    insertion_sort(rand_copy)
    assert_true(utils.compare_arrays(rand_arr, rand_copy), True,
                'Insertion Sort')
Example #13
0
def quick_sort(datalist, start=0, end=None):
    if end is None:
        end = len(datalist)
    size = end - start
    if size <= 1:
        return

    halfway = size // 2 + start
    pivot_choices = [datalist[start], datalist[halfway], datalist[end - 1]]
    insertion_sort(pivot_choices)
    pivot = pivot_choices[1]
    left_pointer = start
    right_pointer = end - 1

    while left_pointer <= right_pointer:
        while datalist[left_pointer] < pivot:
            left_pointer += 1
        while datalist[right_pointer] > pivot:
            right_pointer -= 1
        if left_pointer <= right_pointer:
            datalist[left_pointer], datalist[right_pointer] = \
                datalist[right_pointer], datalist[left_pointer]
            left_pointer += 1
            right_pointer -= 1

    quick_sort(datalist, start, right_pointer + 1)
    quick_sort(datalist, left_pointer, end)
Example #14
0
def quick_sort_two_ways(arr, l, r):
    if r - l <= 15:
        insertion_sort(arr)
        return
    p = partition_two_ways(arr, l, r)
    quick_sort_two_ways(arr, l, p - 1)
    quick_sort_two_ways(arr, p + 1, r)
def merge_sort(a_list):
    if len(a_list) <= 5:
        insertion_sort(a_list)
        return a_list
    mid = len(a_list) // 2
    p1 = a_list[mid:]
    p2 = a_list[:mid]
    p1 = merge_sort(p1)
    p2 = merge_sort(p2)
    i = 0
    j = 0
    merged_list = [None] * (len(p1) + len(p2))
    while i < len(p1) and j < len(p2):
        if p1[i] < p2[j]:
            merged_list[i + j] = p1[i]
            i += 1
        else:
            merged_list[i + j] = p2[j]
            j += 1
    while i < len(p1):
        merged_list[i + j] = p1[i]
        i += 1
    while j < len(p2):
        merged_list[i + j] = p2[j]
        j += 1
    return merged_list
Example #16
0
def timsort(val_list, k):
    if len(val_list) <= k:
        insertion_sort(val_list)
    elif len(val_list) > 1:
        mid_index = len(val_list) // 2
        left = val_list[:mid_index]
        right = val_list[mid_index:]
        
        mergesort(left)
        mergesort(right)
        
        val_index = 0
        l_index = 0
        r_index = 0
        
        while r_index < len(right) and l_index < len(left):
            if right[r_index] < left[l_index]:
                val_list[val_index] = right[r_index]
                r_index += 1
            else:
                val_list[val_index] = left[l_index]
                l_index += 1
            val_index += 1
            
        while r_index < len(right):
            val_list[val_index] = right[r_index]
            r_index += 1
            val_index += 1
            
        while l_index < len(left):
            val_list[val_index] = left[l_index]
            l_index += 1
            val_index += 1
    return(val_list)
 def testInsertion(self):
     result = copy(self.original)
     before = time.time()
     insertion_sort(result)
     after = time.time()
     print("Insertion Sort, size: %d time: %f" % (self.list_length, after-before))
     self.assertEqual(self.sorted_list, result, "Insertion Sort Failed")
Example #18
0
def bucketSort(myList, bucketSize=DEFAULT_BUCKET_SIZE):
    if(len(myList) == 0):
        print('You don\'t have any elements in array!')

    minValue = myList[0]
    maxValue = myList[0]

    # For finding minimum and maximum values
    for i in range(0, len(myList)):
        if myList[i] < minValue:
            minValue = myList[i]
        elif myList[i] > maxValue:
            maxValue = myList[i]

    # Initialize buckets
    bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1
    buckets = []
    for i in range(0, bucketCount):
        buckets.append([])

    # For putting values in buckets
    for i in range(0, len(myList)):
        buckets[math.floor((myList[i] - minValue) / bucketSize)].append(myList[i])

    # Sort buckets and place back into input array
    sortedArray = []
    for i in range(0, len(buckets)):
        insertion_sort(buckets[i])
        for j in range(0, len(buckets[i])):
            sortedArray.append(buckets[i][j])

    return sortedArray
Example #19
0
def bucket_sort(array):
    # n = 0
    largest = max(array)
    length = len(array)
    size = largest / length

    buckets = [[] for _ in range(length)]
    for i in range(length):
        j = int(array[i] / size)
        if j != length:
            buckets[j].append(array[i])
        else:
            buckets[length - 1].append(array[i])
        # n += 1

    for i in range(length):
        # buckets[i], m = insertion_sort.insertion_sort(buckets[i])
        # n += m
        insertion_sort.insertion_sort(buckets[i])

    array = []
    for i in range(length):
        array = array + buckets[i]

    return array
Example #20
0
def quick_sort(datalist, start=0, end=None):
    if end is None:
        end = len(datalist)
    size = end - start
    if size <= 1:
        return

    halfway = size // 2 + start
    pivot_choices = [datalist[start], datalist[halfway], datalist[end - 1]]
    insertion_sort(pivot_choices)
    pivot = pivot_choices[1]
    left_pointer = start
    right_pointer = end - 1

    while left_pointer <= right_pointer:
        while datalist[left_pointer] < pivot:
            left_pointer += 1
        while datalist[right_pointer] > pivot:
            right_pointer -= 1
        if left_pointer <= right_pointer:
            datalist[left_pointer], datalist[right_pointer] = \
                datalist[right_pointer], datalist[left_pointer]
            left_pointer += 1
            right_pointer -= 1

    quick_sort(datalist, start, right_pointer + 1)
    quick_sort(datalist, left_pointer, end)
Example #21
0
def bucket_sort(arr, bucket_size=10):
    """
    桶排序

    算法说明
    1. 设置一个定量的数组当作空桶;
    2. 遍历输入数据,并且把数据一个一个放到对应的桶里去;
    3. 对每个不是空的桶进行排序;
    4. 从不是空的桶里把排好序的数据拼接起来。
    """
    if len(arr) == 0:
        return arr

    min_value = min(arr)
    max_value = max(arr)

    # 桶的初始化
    bucket_count = (max_value - min_value) // bucket_size + 1
    buckets = [[] for i in range(bucket_count)]

    # 利用映射函数将数据分配到各个桶中
    for i in range(len(arr)):
        buckets[(arr[i] - min_value) // bucket_size].append(arr[i])

    arr = []
    for i in range(len(buckets)):
        insertion_sort(buckets[i])
        for j in range(len(buckets[i])):
            arr.append(buckets[i][j])

    return arr
Example #22
0
def bucketSort(myList, bucketSize=DEFAULT_BUCKET_SIZE):
    if (len(myList) == 0):
        print('You don\'t have any elements in array!')

    minValue = myList[0]
    maxValue = myList[0]

    # For finding minimum and maximum values
    for i in range(0, len(myList)):
        if myList[i] < minValue:
            minValue = myList[i]
        elif myList[i] > maxValue:
            maxValue = myList[i]

    # Initialize buckets
    bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1
    buckets = []
    for i in range(0, bucketCount):
        buckets.append([])

    # For putting values in buckets
    for i in range(0, len(myList)):
        buckets[math.floor(
            (myList[i] - minValue) / bucketSize)].append(myList[i])

    # Sort buckets and place back into input array
    sortedArray = []
    for i in range(0, len(buckets)):
        insertion_sort(buckets[i])
        for j in range(0, len(buckets[i])):
            sortedArray.append(buckets[i][j])

    return sortedArray
def merge_insertion_sort(k, items, p, r):
  if k > r - p:
    insertion_sort.insertion_sort(items, p, r)
  else:
    q = (p + r) / 2
    merge_insertion_sort(k, items, p, q)
    merge_insertion_sort(k, items, q + 1, r)
    merge_sort.merge(items, p, q, r)
def test_insertion_sort_not_list_error():
    """Tests that the insertion sort method throws an appropriate error if it's
    called on an object that isn't a valid python list."""
    from insertion_sort import insertion_sort
    test_string = "I am a string.  Huzzah!"
    with pytest.raises(TypeError) as message:
        insertion_sort(test_string)
    assert "Your input must be a Python list." in str(message)
Example #25
0
def bucket_sort(A):
    n = len(A)
    B = [[] for _ in range(n)]
    for i in range(n):
        B[floor(n * A[i])].append(A[i])
    for i in range(n):
        insertion_sort(B[i])
    return [e for sub in B for e in sub]
Example #26
0
def adasort_helper(l, start, end, depth):
    if end <= start + 16:
        insertion_sort(l, start, end)
    elif depth == 0:
        heapsort(l, start, end)
    else:
        bls = hoare_partition(l, start, end)
        adasort_helper(l, start, bls, depth - 1)
        adasort_helper(l, bls + 1, end, depth - 1)
def test_stable():
    """Test identical items in list retain stable position on sort."""
    from insertion_sort import insertion_sort
    check_list = [1, 0, 2, 3, 2]
    two_a = check_list[2]
    two_b = check_list[4]
    insertion_sort(check_list)
    assert check_list[2] is two_a
    assert check_list[3] is two_b
Example #28
0
def test_sorting():
    import random
    datalist = [random.randint(0, 1e8) for i in xrange(100)]

    insertion_sort(datalist)

    previous = datalist[0]
    for i in datalist[1:]:
        assert previous <= i
        previous = i
Example #29
0
def test_weird_insertion_sort():
    ints = [i for i in range(0,10000)]
    mixed_ints = [i for i in range(0,10000)]
    assert ints == mixed_ints
    random.shuffle(mixed_ints)
    assert ints != mixed_ints
    insertion_sort(mixed_ints)
    assert ints == mixed_ints

    
def test_stable_random(seq):
    """Test stability property on random lists."""
    from insertion_sort import insertion_sort
    seq = list(seq)
    index_a, index_b = sorted(random.sample(range(len(seq)), 2))
    val_a, val_b = -1, -1
    seq[index_a], seq[index_b] = val_a, val_b
    insertion_sort(seq)
    assert seq[0] is val_a
    assert seq[1] is val_b
Example #31
0
def bucket_sort(a):
    n = len(a)
    b = [[] for x in range(n)]
    for x in a:
        b[int(n * x)].append(x)
    c = []
    for i in range(n):
        insertion_sort(b[i])
        c += b[i]
    return c
def test_stable_random_2(seq):
    """Test stability property on random lists sorting the other direction."""
    from insertion_sort import insertion_sort
    seq = list(seq)
    index_a, index_b = sorted(random.sample(range(len(seq)), 2))
    val_a, val_b = 1000, 1000
    seq[index_a], seq[index_b] = val_a, val_b
    insertion_sort(seq)
    assert seq[-1] is val_b
    assert seq[-2] is val_a
Example #33
0
def merge_sort1(arr):
    # if len(arr) <= 1:
    #     return arr
    if len(arr) <= 15:
        insertion_sort(arr)
        return arr
    mid = len(arr) // 2
    left = merge_sort1(arr[:mid])
    right = merge_sort1(arr[mid:])
    if arr[:mid][-1] > arr[mid:][0]:
        return merge(left, right)
Example #34
0
def measure_runtime(alg, arr):
    if alg == 'merge':
        start_time = time.time()
        merge_sort(arr, 0, len(arr))
        res = time.time() - start_time
    elif alg == 'insert':
        start_time = time.time()
        insertion_sort(arr)
        res = time.time() - start_time

    return res
def test_insertion_sort():
    for i in range(500):
        array = []

        for j in range(i):
            array.append(random.randrange(-i, i, 1))

        temp = array.copy()
        temp.sort()
        insertion_sort(array)

        assert array == temp
Example #36
0
    def test_insertion_sort(self):
        lst1 = [1, 2, 3, 4, 5]
        lst1 = insertion_sort(lst1)
        self.assertEqual(lst1, [1, 2, 3, 4, 5])

        lst2 = [5, 4, 3, 2, 1]
        lst2 = insertion_sort(lst2)
        self.assertEqual(lst2, [1, 2, 3, 4, 5])

        lst3 = [2, 4, 3, 4, 5, 5, 1]
        lst3 = insertion_sort(lst3)
        self.assertEqual(lst3, [1, 2, 3, 4, 4, 5, 5])
def main(argv):
    progname = argv[0]
    if (len(argv) != 2):
        print 'Usage: {0} <filename>'.format(argv[0])
        print 'Example: {0} random_num.txt'.format(argv[0])
        return 1

    a = read_file_in_array(argv[1]);
    print a
    insertion_sort.insertion_sort(a)
    print a
    return 0
Example #38
0
    def test_insertion_sort(self):
        lst1 = [1, 2, 3, 4, 5]
        lst1 = insertion_sort(lst1)
        self.assertEqual(lst1, [1, 2, 3, 4, 5])

        lst2 = [5, 4, 3, 2, 1]
        lst2 = insertion_sort(lst2)
        self.assertEqual(lst2, [1, 2, 3, 4, 5])

        lst3 = [2, 4, 3, 4, 5, 5, 1]
        lst3 = insertion_sort(lst3)
        self.assertEqual(lst3, [1, 2, 3, 4, 4, 5, 5])
Example #39
0
def test_insertion_sort():
    assert (insertion_sort([5, 2, 4, 6, 1, 3]) == [1, 2, 3, 4, 5, 6])
    assert (insertion_sort([5, 2, 4, 6]) == [2, 4, 5, 6])
    assert (insertion_sort([5, 6, 1, 3]) == [1, 3, 5, 6])
    assert (insertion_sort([5, 2, 6, 1]) == [1, 2, 5, 6])
    assert (insertion_sort([2, 1]) == [1, 2])
    assert (insertion_sort([1, 2]) == [1, 2])
    assert (insertion_sort([2, 1, 1, 1, 2, 1, 3]) == [1, 1, 1, 1, 2, 2, 3])
    assert (insertion_sort([2, 1, 1, 1, 3, 2, 1]) == [1, 1, 1, 1, 2, 2, 3])
    assert (insertion_sort([1]) == [1])
def test_stable_random_3(seq):
    """Test stability property on random lists with random duplicate values."""
    from insertion_sort import insertion_sort
    if len(seq) < 2:
        return
    seq = list(seq)
    index_a = random.randrange(len(seq) - 1)
    index_b = random.randrange(index_a + 1, len(seq))
    val_a = seq[index_a]
    val_b = int(val_a)
    seq[index_b] = val_b
    insertion_sort(seq)
    index_a = seq.index(val_a)
    assert seq[index_a + 1] is val_b
Example #41
0
def bucket_sort(array):
    bucket = [list() for i in range(10)]

    for i in range(len(array)):
        bucket[int(array[i] * 10)].append(array[i])

    for i in range(len(bucket)):
        insertion_sort(bucket[i])

    m = 0
    for i in range(len(bucket)):
        for j in range(len(bucket[i])):
            array[m] = bucket[i][j]
            m += 1
Example #42
0
def bucket_sort(v):
    if not v:
        return v
    nb = max(10, len(v) / 10)
    b = [[] for _ in xrange(nb)]
    m = max(v) * 1.01
    for x in v:
        b[get_bucket(x / m, nb)].append(x)
    res = []
    # print min([len(x) for x in b]), max([len(x) for x in b])
    for i in b:
        insertion_sort(i)
        res += i
    return res
def median(lst, n=5, LEVEL=0):

    if len(lst) <= n:
        array = lst[:]
        insertion_sort.insertion_sort(array)

        idx = len(array)//2
        m = array[idx]

        # print array, m

        return m

    sublists = chunk(lst, n)
    medians = [median(s) for s in sublists]

    return median(medians)
Example #44
0
def bucketsort(A):
    """
    A must be a list of floats s.t. for all x in A, 0 <= x < 1
    >>> bucketsort([0.1, 0.2])
    [0.10000000000000001, 0.20000000000000001]
    >>> bucketsort([0.2, 0.1])
    [0.10000000000000001, 0.20000000000000001]
    >>> bucketsort([])
    []
    """
    n = len(A)
    B = [[] for j in range(0, n)]
    C = []
    for i in xrange(0, n):
        j = int(n*A[i])
        B[j].append(A[i])
    for b in B:
        insertion_sort.insertion_sort(b)
        C = C + b
    return C
Example #45
0
def bucket_sort(a):
	n = len(a)
	# b is a list of n empty lists
	# [[]]*n creates copies of same list
	b = [[] for _ in range(n)]
	# print(b[0],len(b), n)
	# b[1].append(5)
	for i in range(n):
		# x = int(floor(n*a[i]))
		# print(b[x])
		b[floor(n*a[i])].append(a[i])
		# print(b[int(floor(n*a[i]))])
	# print(b)
	# insertion sort to sort in-bucket elements
	for i in range(n):
		insertion_sort(b[i])
	# flatten b
	# print(b)
	flat_sorted = [j for i in b for j in i]
	return flat_sorted
def test_insertion_sort():
    test_list = [randint(1, 50) for i in range(15)]
    test_sorted = insertion_sort(test_list[:])
    if test_sorted == sorted(test_list):
        print("test passes")
        print(test_list)
        print(test_sorted)
    else:
        print("test fails")
        print(test_list)
        print(test_sorted)
    def test_randomly(self):

        for each_pass in range(0, 1000):
            random_list = []
            for each_number in range(0, random.randint(3, 40)):
                random_number = random.randint(0, random.randint(1, 1000))
                random_list.append(random_number)
            sorted_random_list = i_s.insertion_sort(random_list)
            assert len(random_list) == len(sorted_random_list)
            for each_number in range(0, (len(sorted_random_list) - 1)):
                assert (sorted_random_list[each_number]
                        <= sorted_random_list[(each_number + 1)])
def test_sort(make_random_lists):
    
    random_list = make_random_lists

    for a_list in random_list:
        sorted_list = insertion_sort(a_list)
        for j in range(len(a_list)):
            if j == 0:
                continue
            else:
                if sorted_list[j] < sorted_list[j-1]:
                    raise ValueError, sorted_list
def merge_insertion_sort(lst, k=2):
    """
    :description: mergesort not in place

    :time: O(nlogn) this is (intuitively not mathematically) because if you break this problem down into a tree representation of the calls, you see that depth of that tree requires O(n) time and that there are logn depth levels in the tree giving a total run time of O(nlogn)
    :space: O(n), more precisely O(2n) since at the worst point we have to have double the size of the original list in memory (during the last call to merge)
    """
    if len(lst) <= k:
        return insertion_sort.insertion_sort(lst)
    cut = len(lst) / 2
    first = merge_insertion_sort(lst[:cut])
    second = merge_insertion_sort(lst[cut:])
    return merge(first, second)
def main():
  if len(sys.argv) != 2:
    print 'usage: ./compare_sort_algos.py --len_of_array'
    sys.exit(1)

  len_of_array = sys.argv[1] # This argument has length of the array to be sorted.
  print len_of_array
  # Create Random numbers of this length. The random numbers generated are unique.
  array = random.sample(xrange(10000000), int(len_of_array))
  #print array
  sorted_array = insertion_sort.insertion_sort(array)
  insertion_time = time.clock()
  insertion_tot = insertion_time - start_time
  print ("Insertion Sort %s" % insertion_tot)
  sorted_array = selection_sort.selection_sort(array)
  selection_time = time.clock()
  selection_tot = selection_time - insertion_time
  print ("Selection Sort %s" % (selection_tot))
  sorted_array = bubble_sort.bubble_sort(array)
  bubble_time = time.clock()
  bubble_tot = bubble_time - selection_time
  print ("Bubble Sort %s" % (bubble_tot))
  sorted_array_m = merge_sort.merge_sort(array)
  merge_time = time.clock()
  merge_tot = merge_time - bubble_time
  print ("Merge Sort %s" % (merge_tot))
  sorted_array_q = quick_sort.quick_sort(array)
  quick_time = time.clock()
  quick_tot = quick_time - merge_time
  print ("Quick Sort %s" % (quick_tot))
  sorted_array_h = heap_sort.heap_sort(array)
  heap_time = time.clock()
  heap_tot = heap_time - quick_time
  print ("Heap Sort %s" % (heap_tot))
  
  objects = ('Insertion', 'Selection', 'Bubble', 'Merge','Quick','Heap')
  y_pos = np.arange(len(objects))
  performance = [insertion_tot/merge_tot,selection_tot/merge_tot,bubble_tot/merge_tot,merge_tot/merge_tot,quick_tot/merge_tot,heap_tot/merge_tot]
 
  if (sorted_array_m == sorted_array_q):
	print "Merge and Quick sorts are giving the same sorted array results"
  plt.bar(y_pos, performance, align='center', alpha=0.5)
  plt.xticks(y_pos, objects)
  plt.ylabel('Time taken w.r.t merge sort')
  plt.title('Sorting Techniques')
 
  plt.show()
def test_input():
    # Checks that it needs a list
    with pytest.raises(TypeError):
        insertion_sort()

    d = {1: 'one', 2: 'two'}
    with pytest.raises(KeyError):
        insertion_sort(d)

    with pytest.raises(TypeError):
        insertion_sort(None)
    def test_predictably(self):

        dict_of_lists = {
            'list_zero': [0, 0, 0, 0, 0, 0, 0, 0],
            'list_one': [0, 0, 0, 0, 1, 1, 1, 1],
            'list_two': [0, 1, 0, 1, 0, 1, 0, 1],
            'list_three': [0, 1, 1, 0, 1, 1, 0, 0],
            'list_four': [10, 100, 1000000, 10000, 1, 100000, 0, 1000],
            'list_five': [0001, 0010, 0100, 1000, 1100, 0011, 0101, 0110],
        }

        for each_key in dict_of_lists:
            each_list = dict_of_lists[each_key]
            sorted_list = i_s.insertion_sort(each_list)

            assert len(sorted_list) == len(each_list)

            for each_number in range(0, (len(each_list) - 1)):
                assert (sorted_list[each_number]
                        <= sorted_list[(each_number + 1)])
 def test_general_case(self):
     arr = [3, 2, 6, 5, 1, 4]
     self.assertEqual(insertion_sort(arr), [1, 2, 3, 4, 5, 6])
 def test_empty_list(self):
     arr = []
     self.assertEqual(insertion_sort(arr), [])
 def test_singleton_list(self):
     arr = [5]
     self.assertEqual(insertion_sort(arr), [5])