Skip to content

Commit

Permalink
Fix partial heap sort
Browse files Browse the repository at this point in the history
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
  • Loading branch information
erikd committed Nov 22, 2024
1 parent 44287d8 commit 8ca487e
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/Data/Vector/Algorithms/Heap.hs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,8 @@ partialSortByBounds cmp a k l u
| len == 3 = O.sort3ByOffset cmp a l
| len == 4 = O.sort4ByOffset cmp a l
| u <= l + k = sortByBounds cmp a l u
| otherwise = do selectByBounds cmp a k l u
sortHeap cmp a l (l + 4) (l + k)
| otherwise = do selectByBounds cmp a (k + 1) l u
sortHeap cmp a l (l + 4) (l + k + 1)
O.sort4ByOffset cmp a l
where
len = u - l
Expand Down
10 changes: 8 additions & 2 deletions tests/properties/Properties.hs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,14 @@ sanity = 100
prop_partialsort :: (Ord e, Arbitrary e, Show e)
=> (forall s mv. G.MVector mv e => mv s e -> Int -> ST s ())
-> Positive Int -> Property
prop_partialsort = prop_sized $ \algo k ->
prop_sorted . V.take k . modify algo
prop_partialsort = prop_sized $ \algo k v -> do
let newVec = modify algo v
vhead = V.take k newVec
vtail = V.drop k newVec
prop_sorted vhead
.&&.
-- Every element in the head should be < every element in the tail.
if V.null vtail then 1 == 1 else V.maximum vhead <= V.minimum vtail

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

0 comments on commit 8ca487e

Please sign in to comment.