Skip to content

Commit 05226d7

Browse files
Fix flash_sort permutation phase raising IndexError on repeated values
flash_sort([6, 6, 4, 4, 6]) raised IndexError (about 2% of random small inputs). Replace the permutation phase with the standard cycle-leader version and add doctests for two previously failing inputs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 2acda52 commit 05226d7

1 file changed

Lines changed: 20 additions & 23 deletions

File tree

‎sorts/flash_sort.py‎

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ def flash_sort(arr: list[int | float]) -> list[int | float]:
6262
[42]
6363
>>> flash_sort([2.5, 1.1, 3.3, 2.5, 1.1])
6464
[1.1, 1.1, 2.5, 2.5, 3.3]
65+
>>> flash_sort([6, 6, 4, 4, 6])
66+
[4, 4, 6, 6, 6]
67+
>>> flash_sort([8, 3, 8, 6, 8])
68+
[3, 6, 8, 8, 8]
6569
"""
6670
if len(arr) <= 1:
6771
return arr.copy()
@@ -97,32 +101,25 @@ def flash_sort(arr: list[int | float]) -> list[int | float]:
97101
for i in range(1, m):
98102
class_sizes[i] += class_sizes[i - 1]
99103

100-
# Permutation phase
101-
hold = result[0]
104+
# Permutation phase: move every element into its class using cycle leaders.
105+
# class_sizes[k] is now the (exclusive) end position of class k and is
106+
# decremented as elements are placed at the end of their class.
107+
def class_of(value: float) -> int:
108+
return min(int(c1 * (value - min_val)), m - 1)
109+
110+
moves = 0
102111
j = 0
103112
k = m - 1
104-
105-
while j < n - 1:
106-
while j >= class_sizes[k]:
107-
k -= 1
108-
109-
flash = int(c1 * (hold - min_val))
110-
if flash >= m:
111-
flash = m - 1
112-
113-
while j < class_sizes[flash]:
114-
k = flash
115-
class_sizes[k] -= 1
116-
result[j], result[class_sizes[k]] = result[class_sizes[k]], result[j]
117-
hold = result[j]
113+
while moves < n - 1:
114+
while j > class_sizes[k] - 1:
118115
j += 1
119-
flash = int(c1 * (hold - min_val))
120-
if flash >= m:
121-
flash = m - 1
122-
123-
j += 1
124-
if j < n:
125-
hold = result[j]
116+
k = class_of(result[j])
117+
flash = result[j]
118+
while j != class_sizes[k]:
119+
k = class_of(flash)
120+
class_sizes[k] -= 1
121+
result[class_sizes[k]], flash = flash, result[class_sizes[k]]
122+
moves += 1
126123

127124
# Insertion sort for final sorting within classes
128125
for i in range(1, n):

0 commit comments

Comments
 (0)