Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions prometheus/sorting_algorithms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
def tim_sort(array, data_type=int):
"""
Implements the Tim Sort algorithm for sorting an array in ascending order.

:param array: The array to be sorted
:param data_type: The data type of the array elements (default: int)
:return: The sorted array
"""

if not array:
return array

# Minimum run size for small arrays
MIN_RUN = 32

def get_block_size(n):
"""
Calculates the block size for a given length.

:param n: The length of the array segment
:return: The block size
"""
return min(n // 2, MAX_RUN) if n >= MIN_RUN else MIN_RUN

def merge_blocks(left, right, data_type):
"""
Merges two blocks of elements in the array.

:param left: The left block
:param right: The right block
:param data_type: The data type of the array elements
:return: None
"""
result = []
i = j = 0

while i < len(left) and j < len(right):
if data_type(left[i]) <= data_type(right[j]):
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1

result.extend(left[i:])
result.extend(right[j:])

for k, v in enumerate(result):
array[k] = v

def insertion_sort(block, data_type):
"""
Sorts a block of elements using insertion sort.

:param block: The block of elements
:param data_type: The data type of the array elements
:return: None
"""
for i in range(1, len(block)):
key = block[i]
j = i - 1

while j >= 0 and data_type(block[j]) > data_type(key):
block[j + 1] = block[j]
j -= 1

block[j + 1] = key

def sort_blocks(begin, end, data_type):
"""
Sorts a series of blocks using Tim Sort.

:param begin: The beginning index of the series
:param end: The ending index of the series
:param data_type: The data type of the array elements
:return: None
"""
if end - begin < MIN_RUN:
insertion_sort(array[begin:end], data_type)
return

block_size = get_block_size(end - begin)

for i in range(begin, end, block_size):
left_index = i
mid_index = min(i + block_size, end)
right_index = min(i + 2 * block_size, end)

if mid_index < right_index:
merge_blocks(array[left_index:mid_index], array[mid_index:right_index], data_type)

for i in range(begin, end, 2 * block_size):
if mid_index < right_index:
merge_blocks(array[i:mid_index], array[mid_index:right_index], data_type)

sort_blocks(begin, mid_index, data_type)
sort_blocks(mid_index, end, data_type)

MAX_RUN = 64
data_type = get_data_type(array)
sort_blocks(0, len(array), data_type)

return array

def get_data_type(array):
"""
Determines the data type of the array elements.

:param array: The array
:return: The data type
"""
data_types = (int, float, str)

for data_type in data_types:
if all(isinstance(i, data_type) for i in array):
return data_type

raise TypeError("Array contains unsupported data types.")