module AtCoder.Extra.Bisect
(
lowerBound,
lowerBoundIn,
upperBound,
upperBoundIn,
bisectL,
bisectLM,
bisectR,
bisectRM,
)
where
import AtCoder.Internal.Assert qualified as ACIA
import Data.Functor ((<&>))
import Data.Functor.Identity
import Data.Vector.Generic qualified as VG
import GHC.Stack (HasCallStack)
{-# INLINE bisectLImpl #-}
bisectLImpl :: (HasCallStack, Monad m) => (Int -> m Bool) -> Int -> Int -> m Int
bisectLImpl :: forall (m :: * -> *).
(HasCallStack, Monad m) =>
(Int -> m Bool) -> Int -> Int -> m Int
bisectLImpl Int -> m Bool
p Int
l0 = Int -> Int -> m Int
inner (Int
l0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where
inner :: Int -> Int -> m Int
inner Int
l Int
r
| Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
r = Int -> m Int
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
l
| Bool
otherwise =
Int -> m Bool
p Int
mid m Bool -> (Bool -> m Int) -> m Int
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> Int -> Int -> m Int
inner Int
mid Int
r
Bool
False -> Int -> Int -> m Int
inner Int
l Int
mid
where
mid :: Int
mid = (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
r) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2
{-# INLINE bisectRImpl #-}
bisectRImpl :: (HasCallStack, Monad m) => (Int -> m Bool) -> Int -> Int -> m Int
bisectRImpl :: forall (m :: * -> *).
(HasCallStack, Monad m) =>
(Int -> m Bool) -> Int -> Int -> m Int
bisectRImpl Int -> m Bool
p Int
l = ((Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) <$>) (m Int -> m Int) -> (Int -> m Int) -> Int -> m Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> m Bool) -> Int -> Int -> m Int
forall (m :: * -> *).
(HasCallStack, Monad m) =>
(Int -> m Bool) -> Int -> Int -> m Int
bisectLImpl Int -> m Bool
p Int
l
{-# INLINE lowerBound #-}
lowerBound :: (HasCallStack, VG.Vector v a, Ord a) => v a -> a -> Maybe Int
lowerBound :: forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Maybe Int
lowerBound v a
vec = Int -> Int -> v a -> a -> Maybe Int
forall (v :: * -> *) a.
(Vector v a, Ord a) =>
Int -> Int -> v a -> a -> Maybe Int
lowerBoundIn Int
0 (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
vec) v a
vec
{-# INLINE lowerBoundIn #-}
lowerBoundIn :: (VG.Vector v a, Ord a) => Int -> Int -> v a -> a -> Maybe Int
lowerBoundIn :: forall (v :: * -> *) a.
(Vector v a, Ord a) =>
Int -> Int -> v a -> a -> Maybe Int
lowerBoundIn Int
l_ Int
r_ v a
vec a
target
| Int -> Int -> Int -> Bool
ACIA.testInterval Int
l Int
r (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
vec) = HasCallStack => Int -> Int -> (Int -> Bool) -> Maybe Int
Int -> Int -> (Int -> Bool) -> Maybe Int
bisectR Int
l Int
r ((Int -> Bool) -> Maybe Int) -> (Int -> Bool) -> Maybe Int
forall a b. (a -> b) -> a -> b
$ \Int
i -> v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
VG.unsafeIndex v a
vec Int
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
target
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
where
l :: Int
l = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
l_
r :: Int
r = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
vec) Int
r_
{-# INLINE upperBound #-}
upperBound :: (HasCallStack, VG.Vector v a, Ord a) => v a -> a -> Maybe Int
upperBound :: forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Maybe Int
upperBound v a
vec = Int -> Int -> v a -> a -> Maybe Int
forall (v :: * -> *) a.
(Vector v a, Ord a) =>
Int -> Int -> v a -> a -> Maybe Int
upperBoundIn Int
0 (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
vec) v a
vec
{-# INLINE upperBoundIn #-}
upperBoundIn :: (VG.Vector v a, Ord a) => Int -> Int -> v a -> a -> Maybe Int
upperBoundIn :: forall (v :: * -> *) a.
(Vector v a, Ord a) =>
Int -> Int -> v a -> a -> Maybe Int
upperBoundIn Int
l_ Int
r_ v a
vec a
target
| Int -> Int -> Int -> Bool
ACIA.testInterval Int
l Int
r (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
vec) = HasCallStack => Int -> Int -> (Int -> Bool) -> Maybe Int
Int -> Int -> (Int -> Bool) -> Maybe Int
bisectR Int
l Int
r ((Int -> Bool) -> Maybe Int) -> (Int -> Bool) -> Maybe Int
forall a b. (a -> b) -> a -> b
$ \Int
i -> v a -> Int -> a
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
VG.unsafeIndex v a
vec Int
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
target
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
where
l :: Int
l = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
l_
r :: Int
r = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (v a -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length v a
vec) Int
r_
{-# INLINE bisectL #-}
bisectL :: (HasCallStack) => Int -> Int -> (Int -> Bool) -> Maybe Int
bisectL :: HasCallStack => Int -> Int -> (Int -> Bool) -> Maybe Int
bisectL Int
l Int
r Int -> Bool
p = Identity (Maybe Int) -> Maybe Int
forall a. Identity a -> a
runIdentity (Identity (Maybe Int) -> Maybe Int)
-> Identity (Maybe Int) -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int -> Identity Bool) -> Identity (Maybe Int)
forall (m :: * -> *).
(HasCallStack, Monad m) =>
Int -> Int -> (Int -> m Bool) -> m (Maybe Int)
bisectLM Int
l Int
r (Bool -> Identity Bool
forall a. a -> Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Identity Bool) -> (Int -> Bool) -> Int -> Identity Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Bool
p)
{-# INLINE bisectLM #-}
bisectLM :: (HasCallStack, Monad m) => Int -> Int -> (Int -> m Bool) -> m (Maybe Int)
bisectLM :: forall (m :: * -> *).
(HasCallStack, Monad m) =>
Int -> Int -> (Int -> m Bool) -> m (Maybe Int)
bisectLM Int
l Int
r Int -> m Bool
p
| Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
r = Maybe Int -> m (Maybe Int)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise =
(Int -> m Bool) -> Int -> Int -> m Int
forall (m :: * -> *).
(HasCallStack, Monad m) =>
(Int -> m Bool) -> Int -> Int -> m Int
bisectLImpl Int -> m Bool
p Int
l Int
r m Int -> (Int -> Maybe Int) -> m (Maybe Int)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Int
i | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) -> Maybe Int
forall a. Maybe a
Nothing
Int
i -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
{-# INLINE bisectR #-}
bisectR :: (HasCallStack) => Int -> Int -> (Int -> Bool) -> Maybe Int
bisectR :: HasCallStack => Int -> Int -> (Int -> Bool) -> Maybe Int
bisectR Int
l Int
r Int -> Bool
p = Identity (Maybe Int) -> Maybe Int
forall a. Identity a -> a
runIdentity (Identity (Maybe Int) -> Maybe Int)
-> Identity (Maybe Int) -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int -> Int -> (Int -> Identity Bool) -> Identity (Maybe Int)
forall (m :: * -> *).
(HasCallStack, Monad m) =>
Int -> Int -> (Int -> m Bool) -> m (Maybe Int)
bisectRM Int
l Int
r (Bool -> Identity Bool
forall a. a -> Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> Identity Bool) -> (Int -> Bool) -> Int -> Identity Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Bool
p)
{-# INLINE bisectRM #-}
bisectRM :: (HasCallStack, Monad m) => Int -> Int -> (Int -> m Bool) -> m (Maybe Int)
bisectRM :: forall (m :: * -> *).
(HasCallStack, Monad m) =>
Int -> Int -> (Int -> m Bool) -> m (Maybe Int)
bisectRM Int
l Int
r Int -> m Bool
p
| Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
r = Maybe Int -> m (Maybe Int)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise =
(Int -> m Bool) -> Int -> Int -> m Int
forall (m :: * -> *).
(HasCallStack, Monad m) =>
(Int -> m Bool) -> Int -> Int -> m Int
bisectRImpl Int -> m Bool
p Int
l Int
r m Int -> (Int -> Maybe Int) -> m (Maybe Int)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Int
i | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
r -> Maybe Int
forall a. Maybe a
Nothing
Int
i -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i