Skip to content

Commit 2bddc10

Browse files
Add comparable typing to odd-even transposition parallel sort
1 parent 35ccb2c commit 2bddc10

1 file changed

Lines changed: 47 additions & 41 deletions

File tree

‎sorts/odd_even_transposition_parallel.py‎

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,38 @@
1212
"""
1313

1414
import multiprocessing as mp
15+
from typing import Any, Protocol
1516

1617
# lock used to ensure that two processes do not access a pipe at the same time
1718
# NOTE This breaks testing on build runner. May work better locally
1819
# process_lock = mp.Lock()
1920

20-
"""
21-
The function run by the processes that sorts the list
22-
23-
position = the position in the list the process represents, used to know which
24-
neighbor we pass our value to
25-
value = the initial value at list[position]
26-
LSend, RSend = the pipes we use to send to our left and right neighbors
27-
LRcv, RRcv = the pipes we use to receive from our left and right neighbors
28-
resultPipe = the pipe used to send results back to main
29-
"""
3021

22+
class Comparable(Protocol):
23+
def __lt__(self, other: Any, /) -> bool: ...
3124

32-
def oe_process(
33-
position,
34-
value,
35-
l_send,
36-
r_send,
37-
lr_cv,
38-
rr_cv,
39-
result_pipe,
40-
multiprocessing_context,
25+
26+
def oe_process[T: Comparable](
27+
position: int,
28+
value: T,
29+
l_send: tuple[mp.connection.Connection, mp.connection.Connection] | None,
30+
r_send: tuple[mp.connection.Connection, mp.connection.Connection] | None,
31+
lr_cv: tuple[mp.connection.Connection, mp.connection.Connection] | None,
32+
rr_cv: tuple[mp.connection.Connection, mp.connection.Connection] | None,
33+
result_pipe: tuple[mp.connection.Connection, mp.connection.Connection],
34+
multiprocessing_context: Any,
4135
) -> None:
36+
"""
37+
The function run by the processes that sorts the list.
38+
39+
position = the position in the list the process represents, used to know
40+
which neighbor we pass our value to
41+
value = the initial value at list[position]
42+
l_send, r_send = the pipes we use to send to our left and right neighbors
43+
lr_cv, rr_cv = the pipes we use to receive from our left and right
44+
neighbors
45+
result_pipe = the pipe used to send results back to main
46+
"""
4247
process_lock = multiprocessing_context.Lock()
4348

4449
# we perform n swaps since after n swaps we know we are sorted
@@ -71,33 +76,34 @@ def oe_process(
7176
result_pipe[1].send(value)
7277

7378

74-
"""
75-
the function which creates the processes that perform the parallel swaps
76-
77-
arr = the list to be sorted
78-
"""
79-
80-
81-
def odd_even_transposition(arr):
79+
def odd_even_transposition[T: Comparable](arr: list[T]) -> list[T]:
8280
"""
83-
>>> odd_even_transposition(list(range(10)[::-1])) == sorted(list(range(10)[::-1]))
84-
True
85-
>>> odd_even_transposition(["a", "x", "c"]) == sorted(["x", "a", "c"])
86-
True
87-
>>> odd_even_transposition([1.9, 42.0, 2.8]) == sorted([1.9, 42.0, 2.8])
88-
True
89-
>>> odd_even_transposition([False, True, False]) == sorted([False, False, True])
90-
True
91-
>>> odd_even_transposition([1, 32.0, 9]) == sorted([False, False, True])
92-
False
93-
>>> odd_even_transposition([1, 32.0, 9]) == sorted([1.0, 32, 9.0])
81+
Sort a list of comparable items using the parallel odd-even transposition
82+
sort algorithm.
83+
84+
Each element is represented by a separate process; neighboring processes
85+
exchange values in alternating odd/even rounds via message-passing pipes.
86+
Items must be mutually comparable (support ``<``); passing a list whose
87+
elements cannot be compared with each other (e.g. mixing ``int`` and
88+
``str``) raises ``TypeError`` inside the worker processes.
89+
90+
:param arr: a list of mutually comparable items
91+
:return: the same list sorted in ascending order
92+
93+
Examples:
94+
>>> odd_even_transposition([5, 4, 3, 2, 1])
95+
[1, 2, 3, 4, 5]
96+
>>> odd_even_transposition([3, 3, 1, 2, 2, 1])
97+
[1, 1, 2, 2, 3, 3]
98+
>>> odd_even_transposition(['c', 'a', 'b'])
99+
['a', 'b', 'c']
100+
>>> odd_even_transposition([3.3, 1.1, 2.2])
101+
[1.1, 2.2, 3.3]
102+
>>> odd_even_transposition(list(range(10)[::-1])) == sorted(range(10))
94103
True
95104
>>> unsorted_list = [-442, -98, -554, 266, -491, 985, -53, -529, 82, -429]
96105
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list)
97106
True
98-
>>> unsorted_list = [-442, -98, -554, 266, -491, 985, -53, -529, 82, -429]
99-
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list + [1])
100-
False
101107
"""
102108
# spawn method is considered safer than fork
103109
multiprocessing_context = mp.get_context("spawn")

0 commit comments

Comments
 (0)