algokit-py 0.2.0__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- algokit_py/__init__.py +2 -3
- algokit_py/sort/__init__.py +5 -1
- algokit_py/sort/insertion.py +1 -1
- algokit_py/sort/merge.py +43 -0
- algokit_py/sort/quick.py +88 -0
- {algokit_py-0.2.0.dist-info → algokit_py-0.4.0.dist-info}/METADATA +8 -4
- algokit_py-0.4.0.dist-info/RECORD +12 -0
- {algokit_py-0.2.0.dist-info → algokit_py-0.4.0.dist-info}/WHEEL +1 -1
- algokit_py-0.2.0.dist-info/RECORD +0 -10
- {algokit_py-0.2.0.dist-info → algokit_py-0.4.0.dist-info}/top_level.txt +0 -0
algokit_py/__init__.py
CHANGED
|
@@ -3,7 +3,6 @@ algokit_py - A minimal Python algorithms library
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
from algokit_py.search import binary_search, linear_search
|
|
6
|
-
from algokit_py.sort import insertion_sort
|
|
6
|
+
from algokit_py.sort import insertion_sort, merge_sort,quick_sort
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
__all__ = ["binary_search", "linear_search","insertion_sort"]
|
|
8
|
+
__all__ = ["binary_search", "linear_search","insertion_sort","merge_sort","quick_sort"]
|
algokit_py/sort/__init__.py
CHANGED
algokit_py/sort/insertion.py
CHANGED
algokit_py/sort/merge.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Sequence, TypeVar
|
|
2
|
+
|
|
3
|
+
T = TypeVar('T')
|
|
4
|
+
|
|
5
|
+
def merge_sort(sequence: Sequence[T]) -> list[T]:
|
|
6
|
+
"""
|
|
7
|
+
Merge sort implementation.
|
|
8
|
+
|
|
9
|
+
Base case:
|
|
10
|
+
- Sequences of length 0 or 1 are already sorted.
|
|
11
|
+
|
|
12
|
+
Worst Case Time Complexity: O(n log n)
|
|
13
|
+
Space Complexity: O(n)
|
|
14
|
+
"""
|
|
15
|
+
if len(sequence) <= 1:
|
|
16
|
+
return list(sequence)
|
|
17
|
+
|
|
18
|
+
middle = len(sequence) // 2
|
|
19
|
+
left = sequence[:middle]
|
|
20
|
+
right = sequence[middle:]
|
|
21
|
+
|
|
22
|
+
sorted_left = merge_sort(left)
|
|
23
|
+
sorted_right = merge_sort(right)
|
|
24
|
+
|
|
25
|
+
merged = []
|
|
26
|
+
i = j = 0
|
|
27
|
+
|
|
28
|
+
while i < len(sorted_left) and j < len(sorted_right):
|
|
29
|
+
if sorted_left[i] <= sorted_right[j]:
|
|
30
|
+
merged.append(sorted_left[i])
|
|
31
|
+
i += 1
|
|
32
|
+
else:
|
|
33
|
+
merged.append(sorted_right[j])
|
|
34
|
+
j += 1
|
|
35
|
+
|
|
36
|
+
merged.extend(sorted_left[i:])
|
|
37
|
+
merged.extend(sorted_right[j:])
|
|
38
|
+
|
|
39
|
+
return merged
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
algokit_py/sort/quick.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from typing import TypeVar, MutableSequence
|
|
2
|
+
|
|
3
|
+
T = TypeVar("T")
|
|
4
|
+
|
|
5
|
+
# We use mutable sequence because we need to modify the list in place
|
|
6
|
+
def quick_sort(sequence: MutableSequence[T]):
|
|
7
|
+
"""
|
|
8
|
+
In-place Quick Sort implementation using divide-and-conquer.
|
|
9
|
+
|
|
10
|
+
This function sorts the given sequence in place.
|
|
11
|
+
|
|
12
|
+
Average Time Complexity: O(n log n)
|
|
13
|
+
Worst Case Time Complexity: O(n^2)
|
|
14
|
+
Space Complexity: O(log n) due to recursion
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
if len(sequence) <= 1:
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
_quick_sort(sequence, 0, len(sequence) - 1)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _partition(sequence,low,high)-> int:
|
|
24
|
+
"""
|
|
25
|
+
Partition the sequence using the Lomuto partition scheme.
|
|
26
|
+
|
|
27
|
+
This function selects the last element as the pivot and rearranges
|
|
28
|
+
the sequence in place so that:
|
|
29
|
+
- all elements less than or equal to the pivot are placed to its left
|
|
30
|
+
- all elements greater than the pivot are placed to its right
|
|
31
|
+
|
|
32
|
+
The pivot is moved to its final correct position, and its index
|
|
33
|
+
is returned.
|
|
34
|
+
|
|
35
|
+
:param sequence: Mutable sequence to be partitioned
|
|
36
|
+
:param low: Starting index of the subarray
|
|
37
|
+
:param high: Ending index of the subarray (pivot index)
|
|
38
|
+
:return: Final index position of the pivot
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
pivot = sequence[high]
|
|
42
|
+
|
|
43
|
+
# at the start, no elements <= pivot.
|
|
44
|
+
i = low - 1
|
|
45
|
+
|
|
46
|
+
# we need to arrange the sub array into these segments: [≤ pivot | > pivot | pivot]
|
|
47
|
+
for j in range(low,high): # up to high - 1
|
|
48
|
+
if sequence[j] <= pivot:
|
|
49
|
+
i += 1
|
|
50
|
+
sequence[i],sequence[j] = sequence[j],sequence[i]
|
|
51
|
+
|
|
52
|
+
# place pivot in its final position
|
|
53
|
+
sequence[i+1],sequence[high] = sequence[high], sequence[i+1]
|
|
54
|
+
|
|
55
|
+
return i + 1
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _quick_sort(sequence,low,high):
|
|
59
|
+
"""
|
|
60
|
+
Recursively sort a subarray of the sequence in place using Quick Sort.
|
|
61
|
+
|
|
62
|
+
This helper function sorts the elements in the index range
|
|
63
|
+
sequence[low : high + 1] using the divide-and-conquer approach.
|
|
64
|
+
It assumes that the partitioning logic correctly places the pivot
|
|
65
|
+
in its final position and recursively sorts the left and right
|
|
66
|
+
subarrays around the pivot.
|
|
67
|
+
|
|
68
|
+
Base case:
|
|
69
|
+
- If low >= high, the subarray has zero or one element and is already sorted.
|
|
70
|
+
|
|
71
|
+
:param sequence: Mutable sequence to be sorted in place
|
|
72
|
+
:param low: Starting index of the subarray
|
|
73
|
+
:param high: Ending index of the subarray
|
|
74
|
+
:return: None
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
# If the subarray has 0 or 1 element
|
|
78
|
+
# That means it is already sorted
|
|
79
|
+
# This happens when:low >= high
|
|
80
|
+
|
|
81
|
+
if low >= high:
|
|
82
|
+
return # No return: because we do this in place
|
|
83
|
+
|
|
84
|
+
p = _partition(sequence,low,high)
|
|
85
|
+
|
|
86
|
+
_quick_sort(sequence,low,p-1)
|
|
87
|
+
_quick_sort(sequence,p+1,high)
|
|
88
|
+
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: algokit-py
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: A minimal Python algorithms library with clean implementations of search algorithms
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: A minimal Python algorithms library with clean implementations of search algorithms and sort algorithms
|
|
5
5
|
Author: Chanaka Prasanna
|
|
6
6
|
License: MIT
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -23,6 +23,7 @@ Designed for learning, interviews, and real-world algorithm reasoning.
|
|
|
23
23
|
|
|
24
24
|
### Sorting Algorithms
|
|
25
25
|
- Insertion Sort (in-place, stable)
|
|
26
|
+
- Merge Sort (divide-and-conquer, O(n log n))
|
|
26
27
|
|
|
27
28
|
## Usage
|
|
28
29
|
|
|
@@ -42,9 +43,12 @@ print(binary_search([1, 2, 3], 2))
|
|
|
42
43
|
|
|
43
44
|
### Sorting
|
|
44
45
|
```python
|
|
45
|
-
from algokit_py.sort import insertion_sort
|
|
46
|
+
from algokit_py.sort import insertion_sort, merge_sort
|
|
46
47
|
|
|
47
48
|
data = [3, 1, 2]
|
|
49
|
+
|
|
48
50
|
insertion_sort(data)
|
|
49
|
-
print(data)
|
|
51
|
+
print(data) # [1, 2, 3]
|
|
52
|
+
|
|
53
|
+
print(merge_sort([3, 1, 2])) # [1, 2, 3]
|
|
50
54
|
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
algokit_py/__init__.py,sha256=ICtBr06s0mtcZel0LJfX1MPcCmXXtL7e2cdAMThDZ5Q,280
|
|
2
|
+
algokit_py/search/__init__.py,sha256=0xreC43bjUH_VRqJTv48VbPadrY4GQgP7y3PMQ5RR04,118
|
|
3
|
+
algokit_py/search/binary.py,sha256=y9EXEK2wlFuMU6wQfddrESe4CkL2umfH7K0Vl33vW9g,1421
|
|
4
|
+
algokit_py/search/linear.py,sha256=07bjqKVarTmYiC0Uw-Pg_EuNRcsAD4zsn9lfuprTJAc,451
|
|
5
|
+
algokit_py/sort/__init__.py,sha256=a6NZn38kGkpq-uVeXxpMPI_L_VyE8NmIcGRq19sQHls,160
|
|
6
|
+
algokit_py/sort/insertion.py,sha256=CFKnfZESHlwa26TrCjTMZ4pGSPyxAWdwO9CFCwBj1Uo,582
|
|
7
|
+
algokit_py/sort/merge.py,sha256=fyyZhGVqhVIV82oj55IkaG9rGDUvdDCKE6nvD5deNEE,926
|
|
8
|
+
algokit_py/sort/quick.py,sha256=6Tso_KrwduROVziNEKonsA3-5Y5V1EmxRoPxvCg-pLE,2758
|
|
9
|
+
algokit_py-0.4.0.dist-info/METADATA,sha256=Zmqk6bI0rnCPeiNJAo709cP3zdtJJL8MUcCiZONoX0M,1261
|
|
10
|
+
algokit_py-0.4.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
11
|
+
algokit_py-0.4.0.dist-info/top_level.txt,sha256=OqfCkcr7SFcMZHBQVKnTOy6Plaoq8t0A8M4CN6Hca0w,11
|
|
12
|
+
algokit_py-0.4.0.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
algokit_py/__init__.py,sha256=a0JaDxWSgNSg4l9Ezc3Q_ERjw4J72lQuYx7__B89Aio,254
|
|
2
|
-
algokit_py/search/__init__.py,sha256=0xreC43bjUH_VRqJTv48VbPadrY4GQgP7y3PMQ5RR04,118
|
|
3
|
-
algokit_py/search/binary.py,sha256=y9EXEK2wlFuMU6wQfddrESe4CkL2umfH7K0Vl33vW9g,1421
|
|
4
|
-
algokit_py/search/linear.py,sha256=07bjqKVarTmYiC0Uw-Pg_EuNRcsAD4zsn9lfuprTJAc,451
|
|
5
|
-
algokit_py/sort/__init__.py,sha256=9U5wHjwlxvPxOo08uud9xYQ_LrbSV2G1BZJWyoee1ck,37
|
|
6
|
-
algokit_py/sort/insertion.py,sha256=JocOHbztnwaLaTtyMUOnJ5o-BaUih60WX_ooTAVfZp4,574
|
|
7
|
-
algokit_py-0.2.0.dist-info/METADATA,sha256=sNuU_10eTJAJz6XTPjvlYzi11t8ISMu8eMwpjsa3sJE,1136
|
|
8
|
-
algokit_py-0.2.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
9
|
-
algokit_py-0.2.0.dist-info/top_level.txt,sha256=OqfCkcr7SFcMZHBQVKnTOy6Plaoq8t0A8M4CN6Hca0w,11
|
|
10
|
-
algokit_py-0.2.0.dist-info/RECORD,,
|
|
File without changes
|