From f13ad5de9dc5e1976a90ecdbd07465ef72b292fa Mon Sep 17 00:00:00 2001 From: NghiemNgocDuc Date: Tue, 14 Oct 2025 22:02:12 -0400 Subject: [PATCH 1/3] sorting: add sleep_sort (novelty) with doctest --- sorts/sleep_sort.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 sorts/sleep_sort.py diff --git a/sorts/sleep_sort.py b/sorts/sleep_sort.py new file mode 100644 index 000000000000..e69de29bb2d1 From 35e74cbf9a83f2799d3c45dd3add8f163b2c5199 Mon Sep 17 00:00:00 2001 From: NghiemNgocDuc Date: Tue, 14 Oct 2025 22:03:08 -0400 Subject: [PATCH 2/3] ### Summary Add `sort/sleep_sort.py`: a novelty sleep-sort implementation with a simulated mode (safe for CI) and an optional real threaded mode. ### Files added - sort/sleep_sort.py ### Notes - File name is snake_case. - Includes doctests; tested with `python -m doctest -v sort/sleep_sort.py`. - Follows repository style. If this addresses an issue, add: `Fixes #` --- sorts/sleep_sort.py | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/sorts/sleep_sort.py b/sorts/sleep_sort.py index e69de29bb2d1..6c015a852db5 100644 --- a/sorts/sleep_sort.py +++ b/sorts/sleep_sort.py @@ -0,0 +1,100 @@ +# Sleep sort (novelty) implementation +# This provides a fast simulated mode (default) plus an optional real threaded mode. + +from typing import List +import threading +import time + + +def sleep_sort(a: List[int], simulate: bool = True, scale: float = 0.01) -> None: + """ + Sort the list a in-place using the sleep sort idea. + + Behavior: + - Destructive: modifies list a. + - Only accepts integers (positive, zero, or negative). + - Default simulate=True runs instantly by simulating timed wake-ups (safe for tests/CI). + - If simulate=False the function spawns one thread per element and uses time.sleep; + use that mode only for small inputs (and beware of real waiting). + - scale (seconds per unit) applies only when simulate=False. + + >>> a = [3, 1, 2] + >>> b = sorted(a) + >>> sleep_sort(a) # simulated, fast + >>> a == b + True + + >>> a = [0, 0, 1] + >>> sleep_sort(a) + >>> a + [0, 0, 1] + + >>> a = [-2, 1, 0] + >>> sleep_sort(a) + >>> a == sorted([-2, 1, 0]) + True + + >>> sleep_sort([1.5, 2]) # non-integers not allowed + Traceback (most recent call last) + ... + TypeError: integers only please + """ + # quick no-op for empty + if not a: + return + + # type checks + if any(not isinstance(x, int) for x in a): + raise TypeError("integers only please") + + # handle negatives by offsetting so all "sleep times" are non-negative + min_val = min(a) + offset = -min_val if min_val < 0 else 0 + + if simulate: + # Simulated wake-up: bucket by wake time (value + offset), preserve original order + buckets = {} + for idx, val in enumerate(a): + wake = val + offset + buckets.setdefault(wake, []).append((idx, val)) + result: List[int] = [] + for wake in sorted(buckets.keys()): + # append in original order to make stable when values equal + for _, val in buckets[wake]: + result.append(val) + a[:] = result + return + + # Real threaded mode (be careful: this actually sleeps) + results: List[int] = [] + lock = threading.Lock() + + def worker(value: int) -> None: + # sleep proportional to value (after offset), then append to results + time.sleep((value + offset) * scale) + with lock: + results.append(value) + + threads: List[threading.Thread] = [] + for val in a: + t = threading.Thread(target=worker, args=(val,)) + t.daemon = True + t.start() + threads.append(t) + + # wait for threads to finish + for t in threads: + t.join() + + # results is in the order threads woke up + a[:] = results + + +def main() -> None: + a = [8, 3, 2, 7, 4, 6, 8] + sleep_sort(a) # simulated (fast) + print("Sorted order is:", " ".join(map(str, a))) + + +if __name__ == "__main__": + main() From 43b52fb15557432167f66cb0c481090f26f31a1b Mon Sep 17 00:00:00 2001 From: NghiemNgocDuc Date: Tue, 14 Oct 2025 22:22:30 -0400 Subject: [PATCH 3/3] ### Summary Add sorts/sleep_sort.py: a novelty sleep-sort implementation with a simulated mode (safe for CI) and an optional real threaded mode. ### Files added - sorts/sleep_sort.py ### Notes - File name is snake_case. - Includes doctests; tested with python -m doctest -v sort/sleep_sort.py. - Follows repository style. If this addresses an issue, add: Fixes # --- sorts/sleep_sort.py | 79 ++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 48 deletions(-) diff --git a/sorts/sleep_sort.py b/sorts/sleep_sort.py index 6c015a852db5..8387f9718b1c 100644 --- a/sorts/sleep_sort.py +++ b/sorts/sleep_sort.py @@ -1,100 +1,83 @@ -# Sleep sort (novelty) implementation -# This provides a fast simulated mode (default) plus an optional real threaded mode. - from typing import List import threading import time -def sleep_sort(a: List[int], simulate: bool = True, scale: float = 0.01) -> None: +def sleep_sort(numbers: List[int], simulate: bool = True, scale: float = 0.01) -> None: """ - Sort the list a in-place using the sleep sort idea. + Perform Sleep Sort on the given list of integers. + + Sorts the list numbers in place using the Sleep Sort algorithm. Behavior: - - Destructive: modifies list a. + - Destructive: modifies the list numbers. - Only accepts integers (positive, zero, or negative). - Default simulate=True runs instantly by simulating timed wake-ups (safe for tests/CI). - - If simulate=False the function spawns one thread per element and uses time.sleep; - use that mode only for small inputs (and beware of real waiting). + - If simulate=False, the function spawns one thread per element and uses time.sleep; + this mode causes real waiting time proportional to element values. - scale (seconds per unit) applies only when simulate=False. - >>> a = [3, 1, 2] - >>> b = sorted(a) - >>> sleep_sort(a) # simulated, fast - >>> a == b - True + Examples + -------- + >>> nums = [3, 1, 2] + >>> sleep_sort(nums) + >>> nums + [1, 2, 3] - >>> a = [0, 0, 1] - >>> sleep_sort(a) - >>> a + >>> nums = [0, 0, 1] + >>> sleep_sort(nums) + >>> nums [0, 0, 1] - >>> a = [-2, 1, 0] - >>> sleep_sort(a) - >>> a == sorted([-2, 1, 0]) - True + >>> nums = [-2, 1, 0] + >>> sleep_sort(nums) + >>> nums + [-2, 0, 1] - >>> sleep_sort([1.5, 2]) # non-integers not allowed - Traceback (most recent call last) + >>> sleep_sort([1.5, 2]) + Traceback (most recent call last): ... TypeError: integers only please """ - # quick no-op for empty - if not a: + if not numbers: return - # type checks - if any(not isinstance(x, int) for x in a): + if any(not isinstance(x, int) for x in numbers): raise TypeError("integers only please") - # handle negatives by offsetting so all "sleep times" are non-negative - min_val = min(a) + min_val = min(numbers) offset = -min_val if min_val < 0 else 0 if simulate: - # Simulated wake-up: bucket by wake time (value + offset), preserve original order + # Simulated wake-up: bucket by wake time (value + offset), preserve order buckets = {} - for idx, val in enumerate(a): + for idx, val in enumerate(numbers): wake = val + offset buckets.setdefault(wake, []).append((idx, val)) result: List[int] = [] for wake in sorted(buckets.keys()): - # append in original order to make stable when values equal for _, val in buckets[wake]: result.append(val) - a[:] = result + numbers[:] = result return - # Real threaded mode (be careful: this actually sleeps) + # Real threaded mode: causes actual delays proportional to element values results: List[int] = [] lock = threading.Lock() def worker(value: int) -> None: - # sleep proportional to value (after offset), then append to results time.sleep((value + offset) * scale) with lock: results.append(value) threads: List[threading.Thread] = [] - for val in a: + for val in numbers: t = threading.Thread(target=worker, args=(val,)) t.daemon = True t.start() threads.append(t) - # wait for threads to finish for t in threads: t.join() - # results is in the order threads woke up - a[:] = results - - -def main() -> None: - a = [8, 3, 2, 7, 4, 6, 8] - sleep_sort(a) # simulated (fast) - print("Sorted order is:", " ".join(map(str, a))) - - -if __name__ == "__main__": - main() + numbers[:] = results