counting_sort.py
"""⏎
This is pure Python implementation of counting sort algorithm⏎
For doctests run following command:⏎
python -m doctest -v counting_sort.py⏎
or⏎
python3 -m doctest -v counting_sort.py⏎
For manual testing run:⏎
python counting_sort.py⏎
"""⏎
⏎
⏎
def counting_sort(collection):⏎
"""Pure implementation of counting sort algorithm in Python⏎
:param collection: some mutable ordered collection with heterogeneous⏎
comparable items inside⏎
:return: the same collection ordered by ascending⏎
Examples:⏎
>>> counting_sort([0, 5, 3, 2, 2])⏎
[0, 2, 2, 3, 5]⏎
>>> counting_sort([])⏎
[]⏎
>>> counting_sort([-2, -5, -45])⏎
[-45, -5, -2]⏎
"""⏎
# if the collection is empty, returns empty⏎
if collection == []:⏎
return []⏎
⏎
# get some information about the collection⏎
coll_len = len(collection)⏎
coll_max = max(collection)⏎
coll_min = min(collection)⏎
⏎
# create the counting array⏎
counting_arr_length = coll_max + 1 - coll_min⏎
counting_arr = [0] * counting_arr_length⏎
⏎
# count how much a number appears in the collection⏎
for number in collection:⏎
counting_arr[number - coll_min] += 1⏎
⏎
# sum each position with it's predecessors. now, counting_arr[i] tells⏎
# us how many elements <= i has in the collection⏎
for i in range(1, counting_arr_length):⏎
counting_arr[i] = counting_arr[i] + counting_arr[i - 1]⏎
⏎
# create the output collection⏎
ordered = [0] * coll_len⏎
⏎
# place the elements in the output, respecting the original order (stable⏎
# sort) from end to begin, updating counting_arr⏎
for i in reversed(range(0, coll_len)):⏎
ordered[counting_arr[collection[i] - coll_min] - 1] = collection[i]⏎
counting_arr[collection[i] - coll_min] -= 1⏎
⏎
return ordered⏎
⏎
⏎
def counting_sort_string(string):⏎
"""⏎
>>> counting_sort_string("thisisthestring")⏎
'eghhiiinrsssttt'⏎
"""⏎
return "".join([chr(i) for i in counting_sort([ord(c) for c in string])])⏎
⏎
⏎
if __name__ == "__main__":⏎
# Test string sort⏎
assert "eghhiiinrsssttt" == counting_sort_string("thisisthestring")⏎
⏎
user_input = input("Enter numbers separated by a comma:\n").strip()⏎
unsorted = [int(item) for item in user_input.split(",")]⏎
print(counting_sort(unsorted))⏎