4 Commits
2 changed files with 67 additions and 74 deletions
+33 -72
View File
@@ -1,81 +1,42 @@
def send_to_goulag(input_list:list)-> list :
"""Sorts a list of numbers using the unique "Goulag Sort" method.
This algorithm processes a list of numbers through a distinctive iterative and
recursive procedure, inspired by the "Stalin Sort" concept. Here's how it operates:
1. **Iterative Filtering:** It iterates through the main list. If an element
is found to be greater than its subsequent element, the subsequent element
is moved to a temporary holding list (`temp`). The main list then continues
with the remaining elements.
2. **Recursive Processing of Held Items:** If the `temp` list contains more than
one item, the `send_to_goulag` algorithm recursively processes `temp`. This
filtering and holding process continues until the sub-list contains a single
item or becomes empty.
3. **Partial Re-insertion:** After the recursive calls (or if `temp` was empty/single-item),
the algorithm attempts to re-insert the elements from `temp` back into the main list.
This re-insertion is performed by finding a suitable position where the held item
is less than the current element in the main list, maintaining a partial order.
4. **Final Appending:** Any remaining elements in `temp` that were not re-inserted
into the middle of the list are then appended to the end of the main list.
For a more detailed step-by-step explanation of the algorithm's flow, please refer to:
:ref:`goulag_sort_detailed_explanation`.
Args:
input_list (list): The list of numbers to be processed and sorted.
This list will be modified **in-place**.
Returns:
list: The list after being processed by the Goulag Sort algorithm. The result
is an ordered list.
Examples:
>>> from goulag_sort import send_to_goulag
>>> my_list = [5, 2, 8, 1, 9, 4]
>>> send_to_goulag(my_list)
[1, 2, 4, 5, 8, 9]
>>> empty_list = []
>>> send_to_goulag(empty_list)
[]
"""
import copy
idx = 0
temp = []
while True:
def send_to_goulag(main_list:list)->list:
if not main_list:
return main_list
itens_to_be_reinserted = []
if not input_list:
return []
main_list_copy = copy.deepcopy(main_list)
i = 0
while i < len(main_list) - 1:
if main_list[i] > main_list[i+1]:
itens_to_be_reinserted.append(main_list[i+1])
main_list.pop(i+1)
while idx < len(input_list) - 1:
if input_list[idx] > input_list[idx + 1]:
temp.append(input_list[idx + 1])
# pop(idx+1) é uma operação O(N) no pior caso
input_list.pop(idx + 1)
else:
idx += 1
i += 1
# Chamada recursiva (pode adicionar complexidade se for muito frequente)
if len(temp) > 1:
temp = send_to_goulag(temp)
if not itens_to_be_reinserted and main_list == main_list_copy:
return main_list
idx = 0
# Loop para reinserir elementos de 'temp' na lista principal
while idx < len(input_list):
if temp and input_list[idx] > temp[0]:
# Inserção no meio da lista input_list[idx:idx] = temp é O(N) no pior caso
input_list[idx:idx] = temp
temp.clear()
print(main_list)
if len(itens_to_be_reinserted)>1:
itens_to_be_reinserted = send_to_goulag(itens_to_be_reinserted)
i = 0
while i < len(main_list):
if itens_to_be_reinserted[0] < main_list[i]:
main_list[i:i] = itens_to_be_reinserted
itens_to_be_reinserted.clear()
break
idx += 1
if len(temp) == 0:
return input_list
i += 1
main_list = send_to_goulag(main_list)
return main_list
if temp:
input_list.extend(temp) # extend é O(k) onde k é o tamanho de temp
temp.clear()
+32
View File
@@ -5,6 +5,7 @@ import pytest
from goulag_sort import send_to_goulag
def test_empty_list():
assert send_to_goulag([]) == []
@@ -14,6 +15,19 @@ def test_single_element():
def test_already_sorted():
assert send_to_goulag([10,20,45,50,60,100,150]) == [10,20,45,50,60,100,150]
def test_list_all_equal():
assert send_to_goulag([5,5,5,5,5,5,5,5]) == [5,5,5,5,5,5,5,5]
def test_negative_numbers():
inputlist = [-4,15,-10,50,13]
expectedlist = sorted(copy.deepcopy(inputlist))
assert send_to_goulag(inputlist) == expectedlist
def test_float_numbers():
inputlist = [1.7,45.2,10.2,5.4,78.2]
expectedlist = sorted(copy.deepcopy(inputlist))
assert send_to_goulag(inputlist) == expectedlist
def test_reverse_sorted():
inputlist = [50,40,30,25,14,10,5]
expectedlist = [5,10,14,25,30,40,50]
@@ -30,12 +44,30 @@ def test_simple_sort():
expectedlist = sorted(expectedlist)
assert send_to_goulag(inputlist) == expectedlist
def test_partially_sorted_list():
inputlist = [10,20,30,4,12,2,56,15]
expectedlist = copy.deepcopy(inputlist)
expectedlist = sorted(expectedlist)
assert send_to_goulag(inputlist) == expectedlist
def test_duplicated_sort():
inputlist = [10,20,30,30,50,65,100]
expectedList = sorted(copy.deepcopy(inputlist))
assert send_to_goulag(inputlist) == expectedList
def test_list_with_zero_and_negatives():
inputlist = [0,50,-5,2,-10,7,15]
expectedList = sorted(copy.deepcopy(inputlist))
assert send_to_goulag(inputlist) == expectedList
def test_many_duplicates():
input_list = [7, 2, 7, 7, 1, 7, 3, 7]
expected_list = sorted(input_list[:])
assert send_to_goulag(input_list[:]) == expected_list
def test_really_long_sort():
inputList = [random.randint(1,500000) for _ in range(10000)]
expectedList = sorted(copy.deepcopy(inputList))