module Data.IntHeap.MaxTopK where
import qualified Data.List as L
import Data.IntHeap
data MaxTopK = MaxTopK !IntHeap !Int !Int !IntHeap
deriving (MaxTopK -> MaxTopK -> Bool
(MaxTopK -> MaxTopK -> Bool)
-> (MaxTopK -> MaxTopK -> Bool) -> Eq MaxTopK
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MaxTopK -> MaxTopK -> Bool
== :: MaxTopK -> MaxTopK -> Bool
$c/= :: MaxTopK -> MaxTopK -> Bool
/= :: MaxTopK -> MaxTopK -> Bool
Eq)
instance Show MaxTopK where
show :: MaxTopK -> String
show (MaxTopK IntHeap
minHeapL Int
minL Int
maxR IntHeap
maxHeapR) =
([Int], [Int]) -> String
forall a. Show a => a -> String
show
( [Int] -> [Int]
forall a. [a] -> [a]
reverse ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ Int
minL Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: IntHeap -> [Int]
toAscListIH IntHeap
minHeapL
, Int
maxR Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: IntHeap -> [Int]
toDescListIH IntHeap
maxHeapR
)
viewMaxTopK :: MaxTopK -> Int
viewMaxTopK :: MaxTopK -> Int
viewMaxTopK (MaxTopK IntHeap
_ Int
minL Int
_ IntHeap
_) = Int
minL
viewMaxTopKList :: MaxTopK -> [Int]
viewMaxTopKList :: MaxTopK -> [Int]
viewMaxTopKList (MaxTopK IntHeap
minHeapL Int
minL Int
_ IntHeap
_) = IntHeap -> [Int]
toDescListIH IntHeap
minHeapL [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
minL]
newMaxTopK :: Int -> MaxTopK
newMaxTopK :: Int -> MaxTopK
newMaxTopK Int
k = IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK (Int -> Int -> IntHeap
replicateIH (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Int
forall a. Bounded a => a
minBound) Int
forall a. Bounded a => a
minBound Int
forall a. Bounded a => a
minBound IntHeap
emptyIH
buildMaxTopK :: Int -> [Int] -> MaxTopK
buildMaxTopK :: Int -> [Int] -> MaxTopK
buildMaxTopK Int
k [Int]
xs =
Int -> [Int] -> MaxTopK
buildMaxTopKFromDescList Int
k ([Int] -> MaxTopK) -> [Int] -> MaxTopK
forall a b. (a -> b) -> a -> b
$
(Int -> Int -> Ordering) -> [Int] -> [Int]
forall a. (a -> a -> Ordering) -> [a] -> [a]
L.sortBy ((Int -> Int -> Ordering) -> Int -> Int -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare) [Int]
xs
buildMaxTopKFromDescList :: Int -> [Int] -> MaxTopK
buildMaxTopKFromDescList :: Int -> [Int] -> MaxTopK
buildMaxTopKFromDescList Int
k [Int]
xs = case Int -> [Int] -> ([Int], [Int])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [Int]
xs of
([Int]
ls, Int
minL : Int
maxR : [Int]
rs) -> IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK ([Int] -> IntHeap
fromDescListIH [Int]
ls) Int
minL Int
maxR ([Int] -> IntHeap
fromDescListIH [Int]
rs)
([Int]
ls, [Int
minL]) -> IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK ([Int] -> IntHeap
fromDescListIH [Int]
ls) Int
minL Int
forall a. Bounded a => a
minBound IntHeap
emptyIH
([Int]
ls, []) ->
IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK
([Int] -> IntHeap
fromDescListIH ([Int] -> IntHeap) -> ([Int] -> [Int]) -> [Int] -> IntHeap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ([Int] -> IntHeap) -> [Int] -> IntHeap
forall a b. (a -> b) -> a -> b
$ [Int]
ls [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Int -> [Int]
forall a. a -> [a]
repeat Int
forall a. Bounded a => a
minBound)
Int
forall a. Bounded a => a
minBound
Int
forall a. Bounded a => a
minBound
IntHeap
emptyIH
insertMaxTopK ::
Int ->
MaxTopK ->
(Maybe Int, MaxTopK)
insertMaxTopK :: Int -> MaxTopK -> (Maybe Int, MaxTopK)
insertMaxTopK Int
x (MaxTopK IntHeap
minHeapL Int
minL Int
maxR IntHeap
maxHeapR)
| Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
minL =
( Maybe Int
forall a. Maybe a
Nothing
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK IntHeap
minHeapL Int
minL (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
x Int
maxR) (Int -> IntHeap -> IntHeap
insertIH (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
x Int
maxR) IntHeap
maxHeapR)
)
| Bool
otherwise =
case IntHeap -> (Int, IntHeap)
deleteFindMinIH (Int -> IntHeap -> IntHeap
insertIH Int
x IntHeap
minHeapL) of
(Int
minL', IntHeap
minHeapL') ->
( Int -> Maybe Int
forall a. a -> Maybe a
Just Int
minL
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK IntHeap
minHeapL' Int
minL' Int
minL (Int -> IntHeap -> IntHeap
insertIH Int
maxR IntHeap
maxHeapR)
)
deleteMaxTopK ::
Int ->
MaxTopK ->
(Maybe Int, MaxTopK)
deleteMaxTopK :: Int -> MaxTopK -> (Maybe Int, MaxTopK)
deleteMaxTopK Int
x (MaxTopK IntHeap
minHeapL Int
minL Int
maxR IntHeap
maxHeapR)
| Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
maxR =
( Maybe Int
forall a. Maybe a
Nothing
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK IntHeap
minHeapL Int
minL Int
maxR (IntHeap -> MaxTopK) -> IntHeap -> MaxTopK
forall a b. (a -> b) -> a -> b
$ Int -> IntHeap -> IntHeap
deleteIH Int
x IntHeap
maxHeapR
)
| Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
maxR = case IntHeap -> (Int, IntHeap)
deleteFindMax IntHeap
maxHeapR of
(Int
maxR', IntHeap
maxHeapR') ->
( Maybe Int
forall a. Maybe a
Nothing
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK IntHeap
minHeapL Int
minL Int
maxR' IntHeap
maxHeapR'
)
| Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
minL = case IntHeap -> (Int, IntHeap)
deleteFindMax IntHeap
maxHeapR of
(Int
maxR', IntHeap
maxHeapR') ->
( Int -> Maybe Int
forall a. a -> Maybe a
Just Int
maxR
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK IntHeap
minHeapL Int
maxR Int
maxR' IntHeap
maxHeapR'
)
| Int -> IntHeap -> Bool
notMemberIH Int
x IntHeap
minHeapL =
( Maybe Int
forall a. Maybe a
Nothing
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK IntHeap
minHeapL Int
minL Int
maxR IntHeap
maxHeapR
)
| Bool
otherwise = case IntHeap -> (Int, IntHeap)
deleteFindMax IntHeap
maxHeapR of
(Int
maxR', IntHeap
maxHeapR') ->
( Int -> Maybe Int
forall a. a -> Maybe a
Just Int
maxR
, IntHeap -> Int -> Int -> IntHeap -> MaxTopK
MaxTopK (Int -> IntHeap -> IntHeap
insertIH Int
minL (IntHeap -> IntHeap) -> IntHeap -> IntHeap
forall a b. (a -> b) -> a -> b
$ Int -> IntHeap -> IntHeap
deleteIH Int
x IntHeap
minHeapL) Int
maxR Int
maxR' IntHeap
maxHeapR'
)
where
deleteFindMax :: IntHeap -> (Int, IntHeap)
deleteFindMax IntHeap
heap = case IntHeap -> Maybe (Int, IntHeap)
maxViewIH IntHeap
heap of
Just (Int
mm, IntHeap
heap') -> (Int
mm, IntHeap
heap')
Maybe (Int, IntHeap)
Nothing -> (Int
forall a. Bounded a => a
minBound, IntHeap
heap)
exchangeMaxTopK ::
Int ->
Int ->
MaxTopK ->
(Maybe (Int, Int), MaxTopK)
exchangeMaxTopK :: Int -> Int -> MaxTopK -> (Maybe (Int, Int), MaxTopK)
exchangeMaxTopK Int
old Int
new maxTopK :: MaxTopK
maxTopK@(MaxTopK IntHeap
minHeapL Int
minL Int
maxR IntHeap
maxHeapR)
| Int
minL Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
old
, Int
maxR Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
old
, Int
old Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
minL Bool -> Bool -> Bool
|| Int -> IntHeap -> Bool
notMemberIH Int
old IntHeap
minHeapL
, Int
old Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxR Bool -> Bool -> Bool
|| Int -> IntHeap -> Bool
notMemberIH Int
old IntHeap
maxHeapR =
(Maybe (Int, Int)
forall a. Maybe a
Nothing, MaxTopK
maxTopK)
| Int
old Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
new = (Maybe (Int, Int)
forall a. Maybe a
Nothing, MaxTopK
maxTopK)
exchangeMaxTopK Int
old Int
new MaxTopK
maxTopK = case Int -> MaxTopK -> (Maybe Int, MaxTopK)
insertMaxTopK Int
new MaxTopK
maxTopK of
(Maybe Int
Nothing, MaxTopK
maxTopK') -> case Int -> MaxTopK -> (Maybe Int, MaxTopK)
deleteMaxTopK Int
old MaxTopK
maxTopK' of
(Maybe Int
Nothing, MaxTopK
maxTopK'') -> (Maybe (Int, Int)
forall a. Maybe a
Nothing, MaxTopK
maxTopK'')
(Just Int
inserted, MaxTopK
maxTopK'') -> ((Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
inserted, Int
old), MaxTopK
maxTopK'')
(Just Int
deleted, MaxTopK
maxTopK') -> case Int -> MaxTopK -> (Maybe Int, MaxTopK)
deleteMaxTopK Int
old MaxTopK
maxTopK' of
(Maybe Int
Nothing, MaxTopK
maxTopK'') -> ((Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
new, Int
deleted), MaxTopK
maxTopK'')
(Just Int
_inserted, MaxTopK
maxTopK'') -> ((Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
new, Int
old), MaxTopK
maxTopK'')