diff --git a/sorts/bubble_sort.py b/sorts/bubble_sort.py deleted file mode 100644 index 9ec3d5384f38..000000000000 --- a/sorts/bubble_sort.py +++ /dev/null @@ -1,132 +0,0 @@ -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") diff --git a/sorts/sleep_sort.py b/sorts/sleep_sort.py new file mode 100644 index 000000000000..d7ebe0ff7ab2 --- /dev/null +++ b/sorts/sleep_sort.py @@ -0,0 +1,95 @@ +""" +Sleep Sort Algorithm Implementation + +Sleep sort works by creating a separate thread for each element, +where each thread sleeps for a duration proportional to the element's value. +When the thread wakes up, the element is appended to the result list. +Smaller values wake up first, resulting in a sorted list. +""" + +import threading +import time + + +def sleep_sort(arr: list[int]) -> list[int]: + """ + Sort list using sleep sort algorithm. + + Args: + arr: List of non-negative integers + + Returns: + Sorted list in ascending order + + Examples: + >>> sleep_sort([3, 1, 4, 2]) + [1, 2, 3, 4] + >>> sleep_sort([]) + [] + >>> sleep_sort([5]) + [5] + """ + if not arr: + return [] + + result: list[int] = [] + lock = threading.Lock() + + def add_to_result(value: int) -> None: + time.sleep(value) + with lock: + result.append(value) + + threads = [] + for num in arr: + if num < 0: + raise ValueError("Sleep sort only works with non-negative integers") + thread = threading.Thread(target=add_to_result, args=(num,)) + thread.start() + threads.append(thread) + + for thread in threads: + thread.join() + + return result + + +def test_sleep_sort() -> None: + """Test sleep sort algorithm with various test cases.""" + # Test basic functionality + assert sleep_sort([3, 1, 4, 2]) == [1, 2, 3, 4] + + # Test edge cases + assert sleep_sort([]) == [] + assert sleep_sort([5]) == [5] + assert sleep_sort([1, 1, 1]) == [1, 1, 1] + assert sleep_sort([1, 2, 3, 4, 5]) == [1, 2, 3, 4, 5] + assert sleep_sort([5, 4, 3, 2, 1]) == [1, 2, 3, 4, 5] + + print("All tests passed!") + + +if __name__ == "_main_": + # Run automated tests + test_sleep_sort() + + # Interactive demo + try: + user_input = input("Enter numbers separated by commas: ").strip() + if user_input: + numbers = [int(x.strip()) for x in user_input.split(",")] + print(f"Original list: {numbers}") + + # Validate input + if any(num < 0 for num in numbers): + print("Error: Only non-negative integers allowed") + else: + print("Sorting... (wait time = largest number)") + sorted_numbers = sleep_sort(numbers) + print(f"Sorted list: {sorted_numbers}") + else: + print("No input provided.") + except ValueError: + print("Error: Please enter valid integers") + except KeyboardInterrupt: + print("\nProgram interrupted by user.")