Skip to content

Commit 18c82c9

Browse files
Ramvelivelapre-commit-ci[bot]cclauss
authored
Bitonic sort comparable (#15428)
* Make bitonic sort support comparable items * Add comparable item tests for bitonic sort * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent d961217 commit 18c82c9

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

‎sorts/bitonic_sort.py‎

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@
66

77
from __future__ import annotations
88

9+
from typing import Protocol
910

10-
def comp_and_swap(array: list[int], index1: int, index2: int, direction: int) -> None:
11+
12+
class Comparable(Protocol):
13+
def __lt__(self, other: object, /) -> bool: ...
14+
15+
16+
def comp_and_swap[T: Comparable](
17+
array: list[T], index1: int, index2: int, direction: int
18+
) -> None:
1119
"""Compare the value at given index1 and index2 of the array and swap them as per
1220
the given direction.
1321
@@ -32,13 +40,15 @@ def comp_and_swap(array: list[int], index1: int, index2: int, direction: int) ->
3240
>>> arr
3341
[12, 42, -21, 1]
3442
"""
35-
if (direction == 1 and array[index1] > array[index2]) or (
43+
if (direction == 1 and array[index2] < array[index1]) or (
3644
direction == 0 and array[index1] < array[index2]
3745
):
3846
array[index1], array[index2] = array[index2], array[index1]
3947

4048

41-
def bitonic_merge(array: list[int], low: int, length: int, direction: int) -> None:
49+
def bitonic_merge[T: Comparable](
50+
array: list[T], low: int, length: int, direction: int
51+
) -> None:
4252
"""
4353
It recursively sorts a bitonic sequence in ascending order, if direction = 1, and in
4454
descending if direction = 0.
@@ -62,7 +72,9 @@ def bitonic_merge(array: list[int], low: int, length: int, direction: int) -> No
6272
bitonic_merge(array, low + middle, middle, direction)
6373

6474

65-
def bitonic_sort(array: list[int], low: int, length: int, direction: int) -> None:
75+
def bitonic_sort[T: Comparable](
76+
array: list[T], low: int, length: int, direction: int
77+
) -> None:
6678
"""
6779
This function first produces a bitonic sequence by recursively sorting its two
6880
halves in opposite sorting orders, and then calls bitonic_merge to make them in the
@@ -76,6 +88,22 @@ def bitonic_sort(array: list[int], low: int, length: int, direction: int) -> Non
7688
>>> bitonic_sort(arr, 0, 8, 0)
7789
>>> arr
7890
[145, 92, 34, 12, 0, -23, -121, -167]
91+
92+
>>> arr = ["banana", "apple", "cherry", "date"]
93+
>>> bitonic_sort(arr, 0, 4, 1)
94+
>>> arr
95+
['apple', 'banana', 'cherry', 'date']
96+
97+
>>> arr = [3, 1.5, 2, 4.5]
98+
>>> bitonic_sort(arr, 0, 4, 1)
99+
>>> arr
100+
[1.5, 2, 3, 4.5]
101+
102+
>>> arr = [1, "two", 3, "four"]
103+
>>> bitonic_sort(arr, 0, 4, 1)
104+
Traceback (most recent call last):
105+
...
106+
TypeError: '<' not supported between instances of 'str' and 'int'
79107
"""
80108
if length > 1:
81109
middle = int(length / 2)

‎tests/test_sorts.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,18 @@ def test_bogo_sort_comparable_items() -> None:
183183

184184
with pytest.raises(TypeError):
185185
bogo_sort([1, "a"])
186+
187+
188+
def test_bitonic_sort_comparable_items() -> None:
189+
from sorts.bitonic_sort import bitonic_sort
190+
191+
strings = ["banana", "apple", "cherry", "date"]
192+
bitonic_sort(strings, 0, len(strings), 1)
193+
assert strings == ["apple", "banana", "cherry", "date"]
194+
195+
numbers = [3, 1.5, 2, 4.5]
196+
bitonic_sort(numbers, 0, len(numbers), 1)
197+
assert numbers == [1.5, 2, 3, 4.5]
198+
199+
with pytest.raises(TypeError):
200+
bitonic_sort([1, "two", 3, "four"], 0, 4, 1)

0 commit comments

Comments
 (0)