-
-
Notifications
You must be signed in to change notification settings - Fork 46.6k
/
Copy pathsmooth_sort.py
118 lines (96 loc) · 3.01 KB
/
smooth_sort.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""
This is a pure Python implementation of the smoothSort algorithm
Smooth Sort is an algorithm combine the concept of heap sort and the
concept of merge sort It was designed by Edsger W. Dijkstra
and later refined by Steven J. Ross.
More info on: https://en.wikipedia.org/wiki/Smoothsort
For doctests run following command:
python -m doctest -v smooth_sort.py
or
python3 -m doctest -v smooth_sort.py
For manual testing run:
python bogo_sort.py
"""
def smooth_sort(unsorted):
"""
Pure implementation of the smooth sort algorithm using Leonardo numbers in Python
:param unsorted: unordered mutable collection
:return: the same collection ordered in ascending order
Examples:
>>> smooth_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> smooth_sort([])
[]
>>> smooth_sort([-2, -5, -45])
[-45, -5, -2]
"""
def leonardo(leonardo_number):
"""
leonardo number represent numbers in pattern where third number is the sum of
2 preceding numbers plus 1 also leonardo number used in heap construction
every number represent size of tree within the heap
they are used in heapify using max heap approach which we will see later
"""
if leonardo_number < 2:
return 1
return leonardo(leonardo_number - 1) + leonardo(leonardo_number - 2) + 1
def heapify(start, end):
i = start
j = 0
k = 0
while k < end - start + 1:
if k & 0xAAAAAAAA:
j = j + i
i = i >> 1
else:
i = i + j
j = j >> 1
k = k + 1
while i > 0:
j = j >> 1
k = i + j
while k < end:
if unsorted[k] < unsorted[k - i]:
break
unsorted[k], unsorted[k - i] = unsorted[k - i], unsorted[k]
k = k + i
i = j
n = len(unsorted)
if n <= 1:
return unsorted
p = n - 1
q = p
r = 0
while p > 0:
if (r & 0x03) == 0:
heapify(r, q)
if leonardo(r) == p:
r = r + 1
else:
r = r - 1
q = q - leonardo(r)
heapify(r, q)
q = r - 1
r = r + 1
unsorted[0], unsorted[p] = unsorted[p], unsorted[0]
p = p - 1
for i in range(n - 1):
j = i + 1
while j > 0 and unsorted[j] < unsorted[j - 1]:
unsorted[j], unsorted[j - 1] = unsorted[j - 1], unsorted[j]
j = j - 1
return unsorted
if __name__ == "__main__":
import doctest
doctest.testmod()
try:
user_input = input(
"Enter numbers separated by a comma (or press Enter to exit):\n"
).strip()
if not user_input:
print(smooth_sort([]))
else:
unsorted = [int(item) for item in user_input.split(",")]
print(smooth_sort(unsorted))
except ValueError:
print("Invalid input. Please enter valid integers separated by commas.")