Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
131 changes: 0 additions & 131 deletions sorts/bubble_sort.py
Original file line number Diff line number Diff line change
@@ -1,132 +1 @@
from typing import Any


def bubble_sort_iterative(collection: list[Any]) -> list[Any]:
"""Pure implementation of bubble sort algorithm in Python

:param collection: some mutable ordered collection with heterogeneous
comparable items inside
:return: the same collection ordered by ascending

Examples:
>>> bubble_sort_iterative([0, 5, 2, 3, 2])
[0, 2, 2, 3, 5]
>>> bubble_sort_iterative([])
[]
>>> bubble_sort_iterative([-2, -45, -5])
[-45, -5, -2]
>>> bubble_sort_iterative([-23, 0, 6, -4, 34])
[-23, -4, 0, 6, 34]
>>> bubble_sort_iterative([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
True
>>> bubble_sort_iterative([]) == sorted([])
True
>>> bubble_sort_iterative([-2, -45, -5]) == sorted([-2, -45, -5])
True
>>> bubble_sort_iterative([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34])
True
>>> bubble_sort_iterative(['d', 'a', 'b', 'e']) == sorted(['d', 'a', 'b', 'e'])
True
>>> bubble_sort_iterative(['z', 'a', 'y', 'b', 'x', 'c'])
['a', 'b', 'c', 'x', 'y', 'z']
>>> bubble_sort_iterative([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6])
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
>>> bubble_sort_iterative([1, 3.3, 5, 7.7, 2, 4.4, 6])
[1, 2, 3.3, 4.4, 5, 6, 7.7]
>>> import random
>>> collection_arg = random.sample(range(-50, 50), 100)
>>> bubble_sort_iterative(collection_arg) == sorted(collection_arg)
True
>>> import string
>>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100)
>>> bubble_sort_iterative(collection_arg) == sorted(collection_arg)
True
"""
length = len(collection)
for i in reversed(range(length)):
swapped = False
for j in range(i):
if collection[j] > collection[j + 1]:
swapped = True
collection[j], collection[j + 1] = collection[j + 1], collection[j]
if not swapped:
break # Stop iteration if the collection is sorted.
return collection


def bubble_sort_recursive(collection: list[Any]) -> list[Any]:
"""It is similar iterative bubble sort but recursive.

:param collection: mutable ordered sequence of elements
:return: the same list in ascending order

Examples:
>>> bubble_sort_recursive([0, 5, 2, 3, 2])
[0, 2, 2, 3, 5]
>>> bubble_sort_iterative([])
[]
>>> bubble_sort_recursive([-2, -45, -5])
[-45, -5, -2]
>>> bubble_sort_recursive([-23, 0, 6, -4, 34])
[-23, -4, 0, 6, 34]
>>> bubble_sort_recursive([0, 5, 2, 3, 2]) == sorted([0, 5, 2, 3, 2])
True
>>> bubble_sort_recursive([]) == sorted([])
True
>>> bubble_sort_recursive([-2, -45, -5]) == sorted([-2, -45, -5])
True
>>> bubble_sort_recursive([-23, 0, 6, -4, 34]) == sorted([-23, 0, 6, -4, 34])
True
>>> bubble_sort_recursive(['d', 'a', 'b', 'e']) == sorted(['d', 'a', 'b', 'e'])
True
>>> bubble_sort_recursive(['z', 'a', 'y', 'b', 'x', 'c'])
['a', 'b', 'c', 'x', 'y', 'z']
>>> bubble_sort_recursive([1.1, 3.3, 5.5, 7.7, 2.2, 4.4, 6.6])
[1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7]
>>> bubble_sort_recursive([1, 3.3, 5, 7.7, 2, 4.4, 6])
[1, 2, 3.3, 4.4, 5, 6, 7.7]
>>> bubble_sort_recursive(['a', 'Z', 'B', 'C', 'A', 'c'])
['A', 'B', 'C', 'Z', 'a', 'c']
>>> import random
>>> collection_arg = random.sample(range(-50, 50), 100)
>>> bubble_sort_recursive(collection_arg) == sorted(collection_arg)
True
>>> import string
>>> collection_arg = random.choices(string.ascii_letters + string.digits, k=100)
>>> bubble_sort_recursive(collection_arg) == sorted(collection_arg)
True
"""
length = len(collection)
swapped = False
for i in range(length - 1):
if collection[i] > collection[i + 1]:
collection[i], collection[i + 1] = collection[i + 1], collection[i]
swapped = True

return collection if not swapped else bubble_sort_recursive(collection)


if __name__ == "__main__":
import doctest
from random import sample
from timeit import timeit

doctest.testmod()

# Benchmark: Iterative seems slightly faster than recursive.
num_runs = 10_000
unsorted = sample(range(-50, 50), 100)
timer_iterative = timeit(
"bubble_sort_iterative(unsorted[:])", globals=globals(), number=num_runs
)
print("\nIterative bubble sort:")
print(*bubble_sort_iterative(unsorted), sep=",")
print(f"Processing time (iterative): {timer_iterative:.5f}s for {num_runs:,} runs")

unsorted = sample(range(-50, 50), 100)
timer_recursive = timeit(
"bubble_sort_recursive(unsorted[:])", globals=globals(), number=num_runs
)
print("\nRecursive bubble sort:")
print(*bubble_sort_recursive(unsorted), sep=",")
print(f"Processing time (recursive): {timer_recursive:.5f}s for {num_runs:,} runs")
194 changes: 194 additions & 0 deletions sorts/sleep_sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
"""
Sleep Sort Algorithm

Sleep Sort is a humorous sorting algorithm that works by spawning a separate

Check failure on line 4 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W291)

sorts/sleep_sort.py:4:77: W291 Trailing whitespace
thread for each element in the input array. Each thread sleeps for a time

Check failure on line 5 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W291)

sorts/sleep_sort.py:5:74: W291 Trailing whitespace
proportional to the element's value, then adds the element to the sorted list.

Note: This is primarily an educational algorithm and not practical for

Check failure on line 8 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W291)

sorts/sleep_sort.py:8:71: W291 Trailing whitespace
real-world use due to its inefficiency and reliance on thread timing.

Time Complexity: O(max(input) + n)
Space Complexity: O(n)
"""

import threading
import time
from typing import List

Check failure on line 17 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (UP035)

sorts/sleep_sort.py:17:1: UP035 `typing.List` is deprecated, use `list` instead


def sleep_sort(arr: List[int]) -> List[int]:

Check failure on line 20 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (UP006)

sorts/sleep_sort.py:20:35: UP006 Use `list` instead of `List` for type annotation

Check failure on line 20 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (UP006)

sorts/sleep_sort.py:20:21: UP006 Use `list` instead of `List` for type annotation

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/sleep_sort.py, please provide doctest for the function sleep_sort

"""
Sorts a list of non-negative integers using sleep sort algorithm.

Check failure on line 23 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/sleep_sort.py:23:1: W293 Blank line contains whitespace
Args:
arr (List[int]): List of non-negative integers to be sorted

Check failure on line 26 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/sleep_sort.py:26:1: W293 Blank line contains whitespace
Returns:
List[int]: Sorted list in ascending order

Check failure on line 29 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/sleep_sort.py:29:1: W293 Blank line contains whitespace
Examples:
>>> sleep_sort([3, 1, 2])
[1, 2, 3]

Check failure on line 33 in sorts/sleep_sort.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (W293)

sorts/sleep_sort.py:33:1: W293 Blank line contains whitespace
>>> sleep_sort([5, 2, 8, 1])
[1, 2, 5, 8]

>>> sleep_sort([1])
[1]

>>> sleep_sort([])
[]
"""
if not arr:
return []

# Shared result list and lock for thread safety
result = []
lock = threading.Lock()

def worker(value: int) -> None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/sleep_sort.py, please provide doctest for the function worker

"""Worker function that sleeps for value seconds then appends to result."""
time.sleep(value / 10) # Divide by 10 to make it faster for demonstration
with lock:
result.append(value)

# Create and start threads
threads = []
for value in arr:
if value < 0:
raise ValueError("Sleep sort only works with non-negative integers")
thread = threading.Thread(target=worker, args=(value,))
threads.append(thread)
thread.start()

# Wait for all threads to complete
for thread in threads:
thread.join()

return result


def sleep_sort_simple(arr: List[int]) -> List[int]:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/sleep_sort.py, please provide doctest for the function sleep_sort_simple

"""
A simpler version of sleep sort without threads (sequential execution).
This version is more reliable for testing.

Args:
arr (List[int]): List of non-negative integers to be sorted

Returns:
List[int]: Sorted list in ascending order
"""
if not arr:
return []

# Create list of (value, index) pairs
pairs = [(value, i) for i, value in enumerate(arr)]

# Sort based on value
pairs.sort(key=lambda x: x[0])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide descriptive name for the parameter: x


# Extract sorted values
return [value for value, _ in pairs]


class SleepSort:
"""
A class-based implementation of sleep sort with additional features.
"""

def _init_(self, speed_factor: float = 10.0):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/sleep_sort.py, please provide doctest for the function _init_

Please provide return type hint for the function: _init_. If the function does not return a value, please provide the type hint as: def function() -> None:

"""
Initialize SleepSort with a speed factor.

Args:
speed_factor (float): Factor to divide sleep times by (higher = faster)
"""
self.speed_factor = speed_factor

def sort(self, arr: List[int]) -> List[int]:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/sleep_sort.py, please provide doctest for the function sort

"""
Sort the array using sleep sort.

Args:
arr (List[int]): List of non-negative integers

Returns:
List[int]: Sorted list
"""
if not arr:
return []

result = []
lock = threading.Lock()

def worker(value: int) -> None:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file sorts/sleep_sort.py, please provide doctest for the function worker

time.sleep(value / self.speed_factor)
with lock:
result.append(value)

threads = []
for value in arr:
if value < 0:
raise ValueError("Sleep sort only works with non-negative integers")
thread = threading.Thread(target=worker, args=(value,))
threads.append(thread)
thread.start()

for thread in threads:
thread.join()

return result


if __name__ == "_main_":
# Example usage and test cases
import doctest

# Run doctests (using simple version for reliability)
doctest.testmod()

print("=== Sleep Sort Demo ===")

# Test with simple version (more reliable)
test_arr = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"Original array: {test_arr}")

simple_sorted = sleep_sort_simple(test_arr)
print(f"Simple sorted: {simple_sorted}")

# Test with threaded version (may have timing issues in doctests)
try:
threaded_sorted = sleep_sort(test_arr)
print(f"Threaded sorted: {threaded_sorted}")
except Exception as e:
print(f"Threaded version error: {e}")

# Test with class-based version
sorter = SleepSort(speed_factor=20.0)
try:
class_sorted = sorter.sort(test_arr)
print(f"Class sorted: {class_sorted}")
except Exception as e:
print(f"Class version error: {e}")

# Performance comparison
print("\n=== Performance Test ===")
small_arr = [5, 2, 8, 1, 9]

import time as time_module

start = time_module.time()
simple_result = sleep_sort_simple(small_arr)
simple_time = time_module.time() - start
print(f"Simple version: {simple_result} (Time: {simple_time:.4f}s)")

# Demonstrate the algorithm concept
print("\n=== Algorithm Concept ===")
print("1. Each number goes to sleep for n milliseconds")
print("2. Smaller numbers wake up first and get added to result")
print("3. Larger numbers wake up later and get added after")
print("4. Final result is sorted in ascending order!")