diff --git a/merge_sort.py b/merge_sort.py index 963816e..8c4e84e 100755 --- a/merge_sort.py +++ b/merge_sort.py @@ -59,4 +59,4 @@ def merge(left, right): # x100 something_else = [x for x in range(100000)] random.shuffle(something_else) - merge_sort(something_else) \ No newline at end of file + time_merge_sort(merge_sort(something_else)) diff --git a/q_sort.py b/q_sort.py index b69ce31..94ebd9d 100644 --- a/q_sort.py +++ b/q_sort.py @@ -57,4 +57,4 @@ def same_maker(how_many): inputs.append(same_maker(997)) for inp in inputs: - timed_q_sort(inp) + timed_q_sort(inp) \ No newline at end of file diff --git a/r_sort.py b/r_sort.py new file mode 100755 index 0000000..fc5e061 --- /dev/null +++ b/r_sort.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +from merge_sort import timed_func + + +@timed_func +def r_sort(sequence): + digit = 1 + while True: + bins = [[] for i in range(10)] + for x in sequence: + # the expression in bins returns the number in digit place + bins[x % 10 ** digit // 10 ** (digit -1)].append(x) + sequence = [number for x in bins for number in x] + digit += 1 + if len(sequence) == len(bins[0]): + return sequence + + +def str_index(_str, digit): + """Returns the ord of the text at the index of digit""" + try: + index = ord(_str[digit]) + return index + 1 + except IndexError: + return 0 + + +@timed_func +def r_sort_alpha(sequence): + max_digit = 0 + # find the length of longest string + for _str in sequence: + if len(_str) > max_digit: + max_digit = len(_str) + for digit in range(max_digit + 1, -1, -1): + bins = [[] for i in range(257)] + for x in sequence: + index = str_index(x, digit) + bins[index].append(x) + sequence = [number for x in bins for number in x] + return sequence + + +@timed_func +def r_sort_delta(sequence): + digit = 1 + while True: + pos_bins = [[] for i in range(10)] + neg_bins = [[] for i in range(10)] + for x in sequence: + # the expression in bins returns the number in digit place + if x < 0: + neg_bins[abs(x) % 10 ** digit // 10 ** (digit -1)].append(x) + else: + pos_bins[x % 10 ** digit // 10 ** (digit -1)].append(x) + sequence = [number for x in neg_bins[::-1] for number in x] + sequence += [number for x in pos_bins for number in x] + digit += 1 + if len(sequence) == len(pos_bins[0]) + len(neg_bins[0]): + return sequence + + +if __name__ == '__main__': + inputs = [range(500), range(1000)] + inputs.append([10 ** 1000, 1, 2, 3, 4, 5]) + inputs.append(range(6)) + inputs.append(range(1000, 0, -1)) + inputs.append([10 ** 1000, 1, 2, 3, 4, 5] + range(1000, 0 -1)) + print "cases for positive integers:" + for inp in inputs: + r_sort(inp) + + inputs = [['abcdefghijkabcdefghijk' for x in range(1000)]] + inputs.append(['abcdefghijkabcdefghijkabcdefghijkabcdefghijk' for x in range(1000)]) + inputs.append([chr(x) for x in range(256)]) + print "cases for strings:" + for inp in inputs: + r_sort_alpha(inp) diff --git a/test_merge_sort.py b/test_merge_sort.py index 3a06dc7..82148af 100644 --- a/test_merge_sort.py +++ b/test_merge_sort.py @@ -1,6 +1,7 @@ from merge_sort import merge_sort import random + def test_ordered(): something = [x for x in range(100)] actual = merge_sort(something) @@ -14,9 +15,10 @@ def test_reversed(): expected = [x for x in range(1, 1001)] assert actual == expected + def test_random(): something_else = [x for x in range(1000)] random.shuffle(something_else) actual = merge_sort(something_else) expected = [x for x in range(0, 1000)] - assert actual == expected \ No newline at end of file + assert actual == expected diff --git a/test_r_sort.py b/test_r_sort.py new file mode 100644 index 0000000..8b01407 --- /dev/null +++ b/test_r_sort.py @@ -0,0 +1,59 @@ +from r_sort import r_sort_delta, r_sort_alpha, r_sort +from r_sort import r_sort + + +def test_r_one(): + a = [4, 3, 2, 5, 7, 1, 6] + a = r_sort(a) + assert a == [1, 2, 3, 4, 5, 6, 7] + + +def test_r_two(): + a = [5, 5, 5, 5, 5, 5, 5, 5, 5] + a = r_sort(a) + assert a == [5, 5, 5, 5, 5, 5, 5, 5, 5] + + +def test_r_mixed(): + a = [1, 2, 5, 4, 4, 6, 7, 9, 8, 0, 0] + a = r_sort(a) + assert a == [0, 0, 1, 2, 4, 4, 5, 6, 7, 8, 9] + + +def test_r_delta(): + a = [4, 3, 2, 5, 7, 1, 6] + a = r_sort_delta(a) + assert a == [1, 2, 3, 4, 5, 6, 7] + + +def test_r_delta_neg(): + a = [-1, -3, -6, -7, -8, -10, -50] + a = r_sort_delta(a) + assert a == [-50, -10, -8, -7, -6, -3, -1] + + +def test_r_delta_posneg(): + a = [1, -3, -6, 7, -8, 10, -50] + a = r_sort_delta(a) + assert a == [-50, -8, -6, -3, 1, 7, 10] + + +def test_r_alpha_empty(): + """Test empty strings""" + a = ['a', 'b', 'aaa', ''] + a = r_sort_alpha(a) + assert a == ['', 'a', 'aaa', 'b'] + + +def test_r_alpha_shortvlong(): + """Test that 6 character string comes before 5 char string""" + a = ['bbbaa', 'b', 'aaabbb', ''] + a = r_sort_alpha(a) + assert a == ['', 'aaabbb', 'b', 'bbbaa'] + + +def test_r_alpha_zero_char(): + """Test that 6 character string comes before 5 char string""" + a = ['\x00', 'b', 'c', ''] + a = r_sort_alpha(a) + assert a == ['', '\x00', 'b', 'c']