Skip to content

Commit 8ca487e

Browse files
committed
Fix partial heap sort
The function `partialSortByBounds` had an off-by-one error causing all the partial heap sort functions to produce incorrect results. The off-by-one error was fixed and the `prop_partialsort` property test was updated to catch this error. Testing the code before the change fails, while after the change passes. Closes: #46
1 parent 44287d8 commit 8ca487e

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

src/Data/Vector/Algorithms/Heap.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ partialSortByBounds cmp a k l u
188188
| len == 3 = O.sort3ByOffset cmp a l
189189
| len == 4 = O.sort4ByOffset cmp a l
190190
| u <= l + k = sortByBounds cmp a l u
191-
| otherwise = do selectByBounds cmp a k l u
192-
sortHeap cmp a l (l + 4) (l + k)
191+
| otherwise = do selectByBounds cmp a (k + 1) l u
192+
sortHeap cmp a l (l + 4) (l + k + 1)
193193
O.sort4ByOffset cmp a l
194194
where
195195
len = u - l

tests/properties/Properties.hs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,14 @@ sanity = 100
9797
prop_partialsort :: (Ord e, Arbitrary e, Show e)
9898
=> (forall s mv. G.MVector mv e => mv s e -> Int -> ST s ())
9999
-> Positive Int -> Property
100-
prop_partialsort = prop_sized $ \algo k ->
101-
prop_sorted . V.take k . modify algo
100+
prop_partialsort = prop_sized $ \algo k v -> do
101+
let newVec = modify algo v
102+
vhead = V.take k newVec
103+
vtail = V.drop k newVec
104+
prop_sorted vhead
105+
.&&.
106+
-- Every element in the head should be < every element in the tail.
107+
if V.null vtail then 1 == 1 else V.maximum vhead <= V.minimum vtail
102108

103109
prop_sized_empty :: (Ord e) => (forall s. MV.MVector s e -> Int -> ST s ()) -> Property
104110
prop_sized_empty algo = prop_empty (flip algo 0) .&&. prop_empty (flip algo 10)

0 commit comments

Comments
 (0)