Skip to content

Commit 6258663

Browse files
committed
sorts: support comparable items in circle_sort
1 parent d0f9b6e commit 6258663

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

sorts/circle_sort.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,20 @@
88
python3 circle_sort.py
99
"""
1010

11+
from collections.abc import MutableSequence
12+
from typing import Any, Protocol, TypeVar
1113

12-
def circle_sort(collection: list) -> list:
14+
15+
class Comparable(Protocol):
16+
def __lt__(self, other: Any, /) -> bool: ...
17+
18+
19+
T = TypeVar("T", bound=Comparable)
20+
21+
22+
def circle_sort[T: Comparable](
23+
collection: MutableSequence[T],
24+
) -> MutableSequence[T]:
1325
"""A pure Python implementation of circle sort algorithm
1426
1527
:param collection: a mutable collection of comparable items in any order
@@ -22,6 +34,14 @@ def circle_sort(collection: list) -> list:
2234
[]
2335
>>> circle_sort([-2, 5, 0, -45])
2436
[-45, -2, 0, 5]
37+
>>> circle_sort(["d", "a", "c", "b"])
38+
['a', 'b', 'c', 'd']
39+
>>> circle_sort([2.5, -1.0, 0.0])
40+
[-1.0, 0.0, 2.5]
41+
>>> circle_sort([1, "a"])
42+
Traceback (most recent call last):
43+
...
44+
TypeError: '<' not supported between instances of 'str' and 'int'
2545
>>> collections = ([], [0, 5, 3, 2, 2], [-2, 5, 0, -45])
2646
>>> all(sorted(collection) == circle_sort(collection) for collection in collections)
2747
True
@@ -30,10 +50,12 @@ def circle_sort(collection: list) -> list:
3050
if len(collection) < 2:
3151
return collection
3252

33-
def circle_sort_util(collection: list, low: int, high: int) -> bool:
53+
def circle_sort_util(
54+
collection: MutableSequence[T], low: int, high: int
55+
) -> bool:
3456
"""
3557
>>> arr = [5,4,3,2,1]
36-
>>> circle_sort_util(lst, 0, 2)
58+
>>> circle_sort_util(arr, 0, 2)
3759
True
3860
>>> arr
3961
[3, 4, 5, 2, 1]
@@ -48,7 +70,7 @@ def circle_sort_util(collection: list, low: int, high: int) -> bool:
4870
right = high
4971

5072
while left < right:
51-
if collection[left] > collection[right]:
73+
if collection[right] < collection[left]:
5274
collection[left], collection[right] = (
5375
collection[right],
5476
collection[left],
@@ -58,7 +80,7 @@ def circle_sort_util(collection: list, low: int, high: int) -> bool:
5880
left += 1
5981
right -= 1
6082

61-
if left == right and collection[left] > collection[right + 1]:
83+
if left == right and collection[right + 1] < collection[left]:
6284
collection[left], collection[right + 1] = (
6385
collection[right + 1],
6486
collection[left],

tests/test_sorts.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,8 @@ def test_sort_matches_builtin(sort, case):
9292
def test_binary_insertion_sort_rejects_non_comparable_items():
9393
with pytest.raises(TypeError):
9494
binary_insertion_sort([1, "a"])
95+
96+
97+
def test_circle_sort_rejects_non_comparable_items():
98+
with pytest.raises(TypeError):
99+
circle_sort([1, "a"])

0 commit comments

Comments
 (0)