Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b295ee775b | ||
|
|
72279ed09e | ||
|
|
8b42d43574 | ||
|
|
c3b6f95cfb |
@@ -1,12 +0,0 @@
|
|||||||
/* docs/source/_static/custom.css */
|
|
||||||
|
|
||||||
/* Style for the custom 'big-text' role */
|
|
||||||
.big-text {
|
|
||||||
font-size: 2.5em; /* Adjust the size as needed (e.g., 2em, 3em) */
|
|
||||||
font-weight: bold; /* Make it bold for emphasis */
|
|
||||||
color: #cc0000; /* Optional: Change color for more emphasis */
|
|
||||||
display: block; /* Make it a block element to put it on its own line */
|
|
||||||
margin-top: 1em; /* Add some space above */
|
|
||||||
margin-bottom: 1em; /* Add some space below */
|
|
||||||
text-align: center; /* Center the text */
|
|
||||||
}
|
|
||||||
+2
-14
@@ -20,15 +20,11 @@ extensions = ['sphinx.ext.autodoc',
|
|||||||
'sphinx.ext.napoleon',
|
'sphinx.ext.napoleon',
|
||||||
'sphinx.ext.viewcode',
|
'sphinx.ext.viewcode',
|
||||||
'sphinx.ext.todo',
|
'sphinx.ext.todo',
|
||||||
'recommonmark',
|
'recommonmark'
|
||||||
'sphinx_markdown_builder',
|
|
||||||
'sphinxcontrib.mermaid'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
exclude_patterns = [
|
exclude_patterns = []
|
||||||
'build/*'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -38,14 +34,6 @@ exclude_patterns = [
|
|||||||
html_theme = 'sphinx_rtd_theme'
|
html_theme = 'sphinx_rtd_theme'
|
||||||
html_static_path = ['_static']
|
html_static_path = ['_static']
|
||||||
|
|
||||||
html_css_files = [
|
|
||||||
'custom.css',
|
|
||||||
]
|
|
||||||
|
|
||||||
rst_prolog = """
|
|
||||||
.. role:: bigText
|
|
||||||
:class: big-text
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def setup(app):
|
def setup(app):
|
||||||
|
|||||||
@@ -1,106 +1,4 @@
|
|||||||
.. _goulag_sort_detailed_explanation:
|
.. _goulag_sort_detailed_explanation:
|
||||||
|
|
||||||
Goulag Sort Explained
|
Goulag Sort Explained
|
||||||
=====================
|
========================
|
||||||
|
|
||||||
The Goulag Sort is a unique sorting algorithm that builds upon the concept of a "Stalin Sort" but avoids data loss. It achieves this by recursively processing the elements that are removed during the initial filtering step and then re-integrating them into the main list.
|
|
||||||
|
|
||||||
Let's walk through an example using the list: ``[5, 2, 8, 1, 9, 4]``.
|
|
||||||
|
|
||||||
Initial State
|
|
||||||
--------------
|
|
||||||
|
|
||||||
|
|
||||||
The process begins with the original input list:
|
|
||||||
|
|
||||||
.. mermaid::
|
|
||||||
|
|
||||||
graph TD
|
|
||||||
subgraph input_list [ ]
|
|
||||||
direction LR
|
|
||||||
A["5"] --> B["2"] --> C["8"] --> D["1"] --> E["9"] --> F["4"]
|
|
||||||
end
|
|
||||||
style input_list fill:#eee,stroke:#333,stroke-width:2px,rx:5px,ry:5px
|
|
||||||
|
|
||||||
Phase 1: Initial Filtering (Stalin Sort Step)
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
The algorithm iterates through the list, keeping only elements that are less than or equal to the next element. Elements that are *greater* than the next are "removed".
|
|
||||||
|
|
||||||
After this initial filtering pass on ``[5, 2, 8, 1, 9, 4]``:
|
|
||||||
|
|
||||||
The main list becomes:
|
|
||||||
|
|
||||||
.. mermaid::
|
|
||||||
|
|
||||||
graph TD
|
|
||||||
subgraph input_list [ ]
|
|
||||||
direction LR
|
|
||||||
A["5"] --> C["8"] --> E["9"]
|
|
||||||
end
|
|
||||||
style input_list fill:#eee,stroke:#333,stroke-width:2px,rx:5px,ry:5px
|
|
||||||
|
|
||||||
The removed items are collected into a temporary list:
|
|
||||||
|
|
||||||
.. mermaid::
|
|
||||||
|
|
||||||
graph TD
|
|
||||||
subgraph temp_list [ ]
|
|
||||||
direction LR
|
|
||||||
B["2"] --> D["1"] --> F["4"]
|
|
||||||
end
|
|
||||||
style temp_list fill:#eee,stroke:#333,stroke-width:2px,rx:5px,ry:5px
|
|
||||||
|
|
||||||
Phase 2: Recursive Processing of Removed Items
|
|
||||||
------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
The Goulag Sort algorithm is then recursively applied to the temporary list of removed items (``[2, 1, 4]``).
|
|
||||||
|
|
||||||
Processing ``[2, 1, 4]``:
|
|
||||||
- Initial filtering on ``[2, 1, 4]`` removes '1' and '4'.
|
|
||||||
- The sub-list becomes ``[2]``.
|
|
||||||
- The removed items sub-list is ``[1, 4]``.
|
|
||||||
|
|
||||||
The algorithm is then called recursively on ``[1, 4]``:
|
|
||||||
- Initial filtering on ``[1, 4]`` removes '4'.
|
|
||||||
- The sub-list becomes ``[1]``.
|
|
||||||
- The removed items sub-list is ``[4]``.
|
|
||||||
|
|
||||||
The algorithm is then called recursively on ``[4]``:
|
|
||||||
- This list has a single item, so it's returned as is.
|
|
||||||
|
|
||||||
The result of processing ``[1, 4]`` is ``[1]`` (from its sub-list) and ``[4]`` (from its removed list).
|
|
||||||
|
|
||||||
The result of processing ``[2, 1, 4]`` is ``[2]`` (from its sub-list) and the processed result of ``[1, 4]`` (which is ``[1]`` and ``[4]``).
|
|
||||||
|
|
||||||
After the recursive calls complete, the temporary list ``[2, 1, 4]`` is effectively sorted and becomes:
|
|
||||||
|
|
||||||
.. mermaid::
|
|
||||||
|
|
||||||
graph TD
|
|
||||||
subgraph temp_list_processed [ ]
|
|
||||||
direction LR
|
|
||||||
D["1"] --> B["2"] --> F["4"]
|
|
||||||
end
|
|
||||||
style temp_list_processed fill:#eee,stroke:#333,stroke-width:2px,rx:5px,ry:5px
|
|
||||||
|
|
||||||
Phase 3: Re-integration
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
|
|
||||||
The processed temporary list (``[1, 2, 4]``) is then merged back into the main list (``[5, 8, 9]``) in the correct positions.
|
|
||||||
|
|
||||||
The final combined and sorted list is:
|
|
||||||
|
|
||||||
.. mermaid::
|
|
||||||
|
|
||||||
graph TD
|
|
||||||
subgraph final_list [ ]
|
|
||||||
direction LR
|
|
||||||
D["1"] --> B["2"] --> F["4"] --> A["5"] --> C["8"] --> E["9"]
|
|
||||||
end
|
|
||||||
style final_list fill:#eee,stroke:#333,stroke-width:2px,rx:5px,ry:5px
|
|
||||||
|
|
||||||
This process ensures that all elements are eventuad in their correct sorted positions, avoiding the data loss of a simple Stalin Sort.
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _goulag_sort_package_reference:
|
|
||||||
|
|
||||||
goulag_sort Package
|
goulag_sort Package
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ Esta é a documentação da biblioteca Goulag Sort, que implementa um algoritmo
|
|||||||
|
|
||||||
modules
|
modules
|
||||||
goulag_sort_detailed_explanation
|
goulag_sort_detailed_explanation
|
||||||
using_goulag_sort
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
Using Goulag Sort
|
|
||||||
######################
|
|
||||||
First and foremost:
|
|
||||||
|
|
||||||
:bigText:`WHY???????`
|
|
||||||
|
|
||||||
Goulag Sort is not meant to be quick or useful, it is really slow and inefficient.
|
|
||||||
|
|
||||||
But if after this warning you wanna use you can...(I ain't your mother)
|
|
||||||
|
|
||||||
Installing the Library
|
|
||||||
=======================================
|
|
||||||
The Library is available to use using pip but is not available on PyPI
|
|
||||||
|
|
||||||
Why is not available on PyPI
|
|
||||||
+++++++++++++++++++++++++++++
|
|
||||||
This sorting algorithm is extremely bad and is not meant to be taken seriously, so its not fair to be uploaded.
|
|
||||||
|
|
||||||
Installing Via git
|
|
||||||
=========================
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pip install git+https://git.gustavomiranda.xyz/GHMiranda/GoulagSort.git
|
|
||||||
|
|
||||||
Using the Library
|
|
||||||
==============================
|
|
||||||
To use the library firstly you need to import:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from goulag_sort import send_to_goulag
|
|
||||||
|
|
||||||
|
|
||||||
after importing you can call the ``send_to_goulag()`` function
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
>>> from goulag_sort import send_to_goulag
|
|
||||||
|
|
||||||
>>> unordered_list = [80,64,14,25,98,1,74,13,10,5]
|
|
||||||
>>> print(unordered_list)
|
|
||||||
[80,64,14,25,98,1,74,13,10,5]
|
|
||||||
>>> send_to_goulag(unordered_list)
|
|
||||||
>>> print(unordered_list)
|
|
||||||
[1,5,10,13,14,25,64,74,80,98]
|
|
||||||
|
|
||||||
|
|
||||||
to see the function documentation please refer to:
|
|
||||||
:ref:`goulag_sort_package_reference`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+62
-74
@@ -1,81 +1,69 @@
|
|||||||
def send_to_goulag(input_list:list)-> list :
|
import copy
|
||||||
"""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:`Detailed Explanation <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)
|
|
||||||
[]
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
idx = 0
|
def send_to_goulag(main_list:list)->list:
|
||||||
temp = []
|
if not main_list:
|
||||||
while True:
|
return main_list
|
||||||
|
itens_to_be_reinserted = []
|
||||||
|
|
||||||
if not input_list:
|
main_list_copy = copy.deepcopy(main_list)
|
||||||
return []
|
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:
|
else:
|
||||||
if input_list[idx] > input_list[idx + 1]:
|
i += 1
|
||||||
temp.append(input_list[idx + 1])
|
|
||||||
# pop(idx+1) é uma operação O(N) no pior caso
|
if not itens_to_be_reinserted and main_list == main_list_copy:
|
||||||
input_list.pop(idx + 1)
|
return main_list
|
||||||
else:
|
|
||||||
idx += 1
|
|
||||||
|
|
||||||
|
if len(itens_to_be_reinserted)>1:
|
||||||
|
itens_to_be_reinserted = send_to_goulag(itens_to_be_reinserted)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
merge_two_sorted_lists_in_place(main_list,itens_to_be_reinserted)
|
||||||
|
|
||||||
|
main_list = send_to_goulag(main_list)
|
||||||
|
|
||||||
|
return main_list
|
||||||
|
|
||||||
|
def merge_two_sorted_lists_in_place(list1: list, list2: list) -> list:
|
||||||
|
|
||||||
|
if not list2:
|
||||||
|
return list1
|
||||||
|
if not list1:
|
||||||
|
list1.extend(list2)
|
||||||
|
list2.clear()
|
||||||
|
return list1
|
||||||
|
|
||||||
|
|
||||||
|
ptr1 = 0
|
||||||
|
ptr2 = 0
|
||||||
|
|
||||||
|
|
||||||
|
while ptr1 < len(list1) and ptr2 < len(list2):
|
||||||
|
if list1[ptr1] > list2[ptr2]:
|
||||||
|
|
||||||
|
list1.insert(ptr1, list2[ptr2])
|
||||||
|
|
||||||
|
ptr1 += 1
|
||||||
|
|
||||||
|
list2.pop(ptr2)
|
||||||
|
else:
|
||||||
|
|
||||||
|
ptr1 += 1
|
||||||
|
|
||||||
|
|
||||||
|
if list2:
|
||||||
|
list1.extend(list2)
|
||||||
|
list2.clear() # Esvazia list2
|
||||||
|
|
||||||
|
return list1
|
||||||
|
|
||||||
# Chamada recursiva (pode adicionar complexidade se for muito frequente)
|
|
||||||
if len(temp) > 1:
|
|
||||||
temp = send_to_goulag(temp)
|
|
||||||
|
|
||||||
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()
|
|
||||||
break
|
|
||||||
idx += 1
|
|
||||||
if len(temp) == 0:
|
|
||||||
return input_list
|
|
||||||
|
|
||||||
if temp:
|
|
||||||
input_list.extend(temp) # extend é O(k) onde k é o tamanho de temp
|
|
||||||
temp.clear()
|
|
||||||
@@ -5,6 +5,7 @@ import pytest
|
|||||||
from goulag_sort import send_to_goulag
|
from goulag_sort import send_to_goulag
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_empty_list():
|
def test_empty_list():
|
||||||
assert send_to_goulag([]) == []
|
assert send_to_goulag([]) == []
|
||||||
|
|
||||||
@@ -14,6 +15,19 @@ def test_single_element():
|
|||||||
def test_already_sorted():
|
def test_already_sorted():
|
||||||
assert send_to_goulag([10,20,45,50,60,100,150]) == [10,20,45,50,60,100,150]
|
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():
|
def test_reverse_sorted():
|
||||||
inputlist = [50,40,30,25,14,10,5]
|
inputlist = [50,40,30,25,14,10,5]
|
||||||
expectedlist = [5,10,14,25,30,40,50]
|
expectedlist = [5,10,14,25,30,40,50]
|
||||||
@@ -30,12 +44,30 @@ def test_simple_sort():
|
|||||||
expectedlist = sorted(expectedlist)
|
expectedlist = sorted(expectedlist)
|
||||||
assert send_to_goulag(inputlist) == 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():
|
def test_duplicated_sort():
|
||||||
inputlist = [10,20,30,30,50,65,100]
|
inputlist = [10,20,30,30,50,65,100]
|
||||||
expectedList = sorted(copy.deepcopy(inputlist))
|
expectedList = sorted(copy.deepcopy(inputlist))
|
||||||
|
|
||||||
assert send_to_goulag(inputlist) == expectedList
|
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():
|
def test_really_long_sort():
|
||||||
inputList = [random.randint(1,500000) for _ in range(10000)]
|
inputList = [random.randint(1,500000) for _ in range(10000)]
|
||||||
expectedList = sorted(copy.deepcopy(inputList))
|
expectedList = sorted(copy.deepcopy(inputList))
|
||||||
|
|||||||
Reference in New Issue
Block a user