Skip to content

Commit 60cea20

Browse files
5h4d0wn1kayushman-itcclauss
authored
feat(sorts): make odd-even transposition generic over comparable items (#15405)
Part of #15234 - Replace list[Any] with a Comparable-bounded TypeVar so odd_even_transposition sorts any mutually comparable items, not just ints - Add str/float/int success doctests plus a TypeError rejection doctest for non-comparable mixed input - Assert in-place behavior via `result is values` doctest - Register the sort in the shared battery and in test_sort_rejects_non_comparable_items Co-authored-by: ayushman-it <253447966+ayushman-it@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent cce4d26 commit 60cea20

2 files changed

Lines changed: 65 additions & 11 deletions

File tree

‎sorts/odd_even_transposition_single_threaded.py‎

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,80 @@
55
66
Normally the swaps in each set happen simultaneously, without that the algorithm
77
is no better than bubble sort.
8+
9+
For doctests run following command:
10+
python3 -m doctest -v odd_even_transposition_single_threaded.py
11+
12+
For manual testing run:
13+
python3 odd_even_transposition_single_threaded.py
814
"""
915

16+
from typing import Any, Protocol
17+
1018

11-
def odd_even_transposition(arr: list) -> list:
19+
class Comparable(Protocol):
20+
def __lt__(self, other: Any, /) -> bool: ...
21+
22+
23+
def odd_even_transposition[T: Comparable](collection: list[T]) -> list[T]:
1224
"""
13-
>>> odd_even_transposition([5, 4, 3, 2, 1])
14-
[1, 2, 3, 4, 5]
25+
Sort a list in place using the odd-even transposition sort algorithm.
26+
27+
The algorithm alternates between comparing-and-swapping even-indexed and
28+
odd-indexed adjacent pairs until the collection is fully sorted. Because
29+
each pass compares a disjoint set of pairs, the passes can be parallelized;
30+
this implementation walks the pairs sequentially.
1531
16-
>>> odd_even_transposition([13, 11, 18, 0, -1])
17-
[-1, 0, 11, 13, 18]
32+
:param collection: a mutable ordered collection with comparable items
33+
:return: the same collection, sorted in ascending order
1834
19-
>>> odd_even_transposition([-.1, 1.1, .1, -2.9])
20-
[-2.9, -0.1, 0.1, 1.1]
35+
Examples:
36+
>>> odd_even_transposition([5, 4, 3, 2, 1])
37+
[1, 2, 3, 4, 5]
38+
>>> odd_even_transposition([13, 11, 18, 0, -1]) == sorted([13, 11, 18, 0, -1])
39+
True
40+
>>> odd_even_transposition([-.1, 1.1, .1, -2.9]) == sorted([-.1, 1.1, .1, -2.9])
41+
True
42+
>>> odd_even_transposition([])
43+
[]
44+
>>> odd_even_transposition([3, 3, 1, 2, 2, 1])
45+
[1, 1, 2, 2, 3, 3]
46+
>>> odd_even_transposition(['c', 'a', 'b']) == sorted(['c', 'a', 'b'])
47+
True
48+
>>> odd_even_transposition([3.3, 1.1, 2.2]) == sorted([3.3, 1.1, 2.2])
49+
True
50+
>>> values = [4, 2, 7, 1]
51+
>>> result = odd_even_transposition(values)
52+
>>> result is values
53+
True
54+
>>> values
55+
[1, 2, 4, 7]
56+
>>> import random
57+
>>> collection = random.sample(range(-50, 50), 100)
58+
>>> odd_even_transposition(collection) == sorted(collection)
59+
True
60+
>>> import string
61+
>>> collection = random.choices(string.ascii_letters + string.digits, k=100)
62+
>>> odd_even_transposition(collection) == sorted(collection)
63+
True
64+
>>> odd_even_transposition([1, "a"]) # doctest: +IGNORE_EXCEPTION_DETAIL
65+
Traceback (most recent call last):
66+
...
67+
TypeError: '<' not supported between instances of 'str' and 'int'
2168
"""
22-
arr_size = len(arr)
69+
arr_size = len(collection)
2370
for _ in range(arr_size):
2471
for i in range(_ % 2, arr_size - 1, 2):
25-
if arr[i + 1] < arr[i]:
26-
arr[i], arr[i + 1] = arr[i + 1], arr[i]
72+
if collection[i + 1] < collection[i]:
73+
collection[i], collection[i + 1] = collection[i + 1], collection[i]
2774

28-
return arr
75+
return collection
2976

3077

3178
if __name__ == "__main__":
79+
from doctest import testmod
80+
81+
testmod()
82+
3283
arr = list(range(10, 0, -1))
3384
print(f"Original: {arr}. Sorted: {odd_even_transposition(arr)}")

‎tests/test_sorts.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from sorts.iterative_merge_sort import iter_merge_sort
3838
from sorts.merge_sort import merge_sort
3939
from sorts.odd_even_sort import odd_even_sort
40+
from sorts.odd_even_transposition_single_threaded import odd_even_transposition
4041
from sorts.pancake_sort import pancake_sort
4142
from sorts.patience_sort import patience_sort
4243
from sorts.quick_sort import quick_sort
@@ -74,6 +75,7 @@ def test_heap_sort() -> None:
7475
merge,
7576
merge_sort,
7677
odd_even_sort,
78+
odd_even_transposition,
7779
pancake_sort,
7880
patience_sort,
7981
quick_sort,
@@ -145,6 +147,7 @@ def test_rec_insertion_sort(case) -> None:
145147
merge,
146148
merge_sort,
147149
odd_even_sort,
150+
odd_even_transposition,
148151
pancake_sort,
149152
reversort,
150153
selection_sort,

0 commit comments

Comments
 (0)