{-# language BangPatterns, RankNTypes, ScopedTypeVariables #-}
module Data.Vector.Algorithms where
import Prelude hiding (length)
import Control.Monad
import Control.Monad.Primitive
import Control.Monad.ST (runST)
import Data.Vector.Generic.Mutable
import qualified Data.Vector.Generic as V
import qualified Data.Vector.Unboxed.Mutable as UMV
import qualified Data.Bit as Bit
import Data.Vector.Algorithms.Common (Comparison)
import Data.Vector.Algorithms.Intro (sortUniqBy)
import qualified Data.Vector.Algorithms.Search  as S
nub :: forall v e . (V.Vector v e, Ord e) => v e -> v e
nub :: v e -> v e
nub = Comparison e -> v e -> v e
forall (v :: * -> *) e. Vector v e => Comparison e -> v e -> v e
nubBy Comparison e
forall a. Ord a => a -> a -> Ordering
compare
nubBy ::
  forall v e . (V.Vector v e) =>
  Comparison e -> v e -> v e
nubBy :: Comparison e -> v e -> v e
nubBy Comparison e
cmp v e
vec = (forall s. ST s (v e)) -> v e
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (v e)) -> v e) -> (forall s. ST s (v e)) -> v e
forall a b. (a -> b) -> a -> b
$ do
  Mutable v s e
mv <- v e -> ST s (Mutable v (PrimState (ST s)) e)
forall (m :: * -> *) (v :: * -> *) a.
(PrimMonad m, Vector v a) =>
v a -> m (Mutable v (PrimState m) a)
V.unsafeThaw v e
vec 
  Mutable v s e
destMV <- (Comparison e
 -> Mutable v (PrimState (ST s)) e
 -> ST s (Mutable v (PrimState (ST s)) e))
-> Comparison e
-> Mutable v (PrimState (ST s)) e
-> ST s (Mutable v (PrimState (ST s)) e)
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
(Comparison e -> v (PrimState m) e -> m (v (PrimState m) e))
-> Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
nubByMut Comparison e
-> Mutable v (PrimState (ST s)) e
-> ST s (Mutable v (PrimState (ST s)) e)
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
sortUniqBy Comparison e
cmp Mutable v s e
Mutable v (PrimState (ST s)) e
mv
  v e
v <- Mutable v (PrimState (ST s)) e -> ST s (v e)
forall (m :: * -> *) (v :: * -> *) a.
(PrimMonad m, Vector v a) =>
Mutable v (PrimState m) a -> m (v a)
V.unsafeFreeze Mutable v s e
Mutable v (PrimState (ST s)) e
destMV
  v e -> ST s (v e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (v e -> v e
forall (v :: * -> *) a. Vector v a => v a -> v a
V.force v e
v)
nubByMut ::
  forall m v e . (PrimMonad m, MVector v e) =>
  (Comparison e -> v (PrimState m) e -> m (v (PrimState m) e))
  -> Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
nubByMut :: (Comparison e -> v (PrimState m) e -> m (v (PrimState m) e))
-> Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
nubByMut Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
alg Comparison e
cmp v (PrimState m) e
inp = do
  let len :: Int
len = v (PrimState m) e -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
length v (PrimState m) e
inp
  v (PrimState m) e
inp' <- v (PrimState m) e -> m (v (PrimState m) e)
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> m (v (PrimState m) a)
clone v (PrimState m) e
inp
  v (PrimState m) e
sortUniqs <- Comparison e -> v (PrimState m) e -> m (v (PrimState m) e)
alg Comparison e
cmp v (PrimState m) e
inp'
  let uniqLen :: Int
uniqLen = v (PrimState m) e -> Int
forall (v :: * -> * -> *) a s. MVector v a => v s a -> Int
length v (PrimState m) e
sortUniqs
  MVector (PrimState m) Bit
bitmask <- Int -> Bit -> m (MVector (PrimState m) Bit)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
UMV.replicate Int
uniqLen (Bool -> Bit
Bit.Bit Bool
False) 
                                                   
  dest ::  v (PrimState m) e <- Int -> m (v (PrimState m) e)
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
Int -> m (v (PrimState m) a)
unsafeNew Int
uniqLen  
  let
    go :: Int -> Int -> m ()
    go :: Int -> Int -> m ()
go !Int
srcInd !Int
destInd
      | Int
srcInd Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      | Int
destInd Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
uniqLen = () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
      | Bool
otherwise = do
          e
curr    <- v (PrimState m) e -> Int -> m e
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
unsafeRead v (PrimState m) e
inp Int
srcInd                
          Int
sortInd <- Comparison e -> v (PrimState m) e -> e -> m Int
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> e -> m Int
S.binarySearchBy Comparison e
cmp v (PrimState m) e
sortUniqs e
curr  
          Bit
bit <- MVector (PrimState m) Bit -> Int -> m Bit
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UMV.unsafeRead MVector (PrimState m) Bit
bitmask Int
sortInd           
                                                          
          case Bit
bit of
            
            Bit.Bit Bool
True -> Int -> Int -> m ()
go (Int
srcInd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int
destInd
            
            
            Bit.Bit Bool
False -> do
              MVector (PrimState m) Bit -> Int -> Bit -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UMV.unsafeWrite MVector (PrimState m) Bit
bitmask Int
sortInd (Bool -> Bit
Bit.Bit Bool
True)
              v (PrimState m) e -> Int -> e -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
unsafeWrite v (PrimState m) e
dest Int
destInd e
curr
              Int -> Int -> m ()
go (Int
srcInd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
destInd Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  Int -> Int -> m ()
go Int
0 Int
0
  v (PrimState m) e -> m (v (PrimState m) e)
forall (f :: * -> *) a. Applicative f => a -> f a
pure v (PrimState m) e
dest