結果

問題 No.998 Four Integers
ユーザー こまる
提出日時 2020-10-31 11:07:51
言語 Haskell
(9.10.1)
結果
CE  
(最新)
AC  
(最初)
実行時間 -
コード長 18,775 bytes
コンパイル時間 1,218 ms
コンパイル使用メモリ 189,964 KB
最終ジャッジ日時 2024-11-14 23:53:45
合計ジャッジ時間 1,628 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。

コンパイルメッセージ
Loaded package environment from /home/judge/.ghc/x86_64-linux-9.8.2/environments/default
[1 of 2] Compiling Main             ( Main.hs, Main.o )

Main.hs:319:17: error: [GHC-87543]
    Ambiguous occurrence ‘.>>.’.
    It could refer to
       either ‘Data.Bits..>>.’,
              imported from ‘Data.Bits’ at Main.hs:8:1-26,
           or ‘Main..>>.’, defined at Main.hs:543:1.
    |
319 | minrun n0 = (n0 .>>. extra) + if (lowMask .&. n0) > 0 then 1 else 0
    |                 ^^^^

Main.hs:321:22: error: [GHC-87543]
    Ambiguous occurrence ‘.>>.’.
    It could refer to
       either ‘Data.Bits..>>.’,
              imported from ‘Data.Bits’ at Main.hs:8:1-26,
           or ‘Main..>>.’, defined at Main.hs:543:1.
    |
321 |     !n1 = n0 .|. (n0 .>>. 1)
    |                      ^^^^

Main.hs:322:22: error: [GHC-87543]
    Ambiguous occurrence ‘.>>.’.
    It could refer to
       either ‘Data.Bits..>>.’,
              imported from ‘Data.Bits’ at Main.hs:8:1-26,
           or ‘Main..>>.’, defined at Main.hs:543:1.
    |
322 |     !n2 = n1 .|. (n1 .>>. 2)
    |                      ^^^^

Main.hs:323:22: error: [GHC-87543]
    Ambiguous occurrence ‘.>>.’.
    It could refer to
       either ‘Data.Bits..>>.’,
              imported from ‘Data.Bits’ at Main.hs:8:1-26,
           or ‘Main..>>.’, defined at Main.hs:543:1.
    |
323 |     !n3 = n2 .|. (n2 .>>. 4)
    |                      ^^^^

Main.hs:324:22: error: [GHC-87543]
    Ambiguous occurrence ‘.>>.’.
    It could refer to
       either ‘Data.Bits..>>.’,
              imported from ‘Data.Bits’ at Main.hs:8:1-26,
           or ‘Main..>>.’, defined at Main.hs:543:1.
    |
324 |     !n4 = n3 .|. (n3 .>>. 8)
    |                      ^^^^

Main.hs:325:22: error: [GHC-87543]
    Ambiguous occurrence ‘.>>.’.
    It could refer to
       either ‘Data.Bits..>>.’,
              imported from ‘Data.Bits’ at Main.hs:8:1-26,
       

ソースコード

diff #
プレゼンテーションモードにする

{-# LANGUAGE BangPatterns #-}
module Main where
import Control.Monad
import Control.Monad.ST
import Control.Monad.State
import Data.Bits
import Data.Bool
import Data.Char
import Data.Coerce
import qualified Data.ByteString.Char8 as BSC8
import qualified Data.Vector.Generic.Mutable as VGM
import qualified Data.Vector.Unboxed as VU
main :: IO ()
main = do
xs <- seqInput 4
putStrLn $ bool "No" "Yes" (solve xs)
solve :: VU.Vector Int -> Bool
solve xs = runST $ do
ys <- VU.unsafeThaw xs
timSort ys
zs <- VU.unsafeFreeze ys
let
a = zs VU.! 0
b = zs VU.! 1
c = zs VU.! 2
d = zs VU.! 3
return ((a + 1 == b) && (b + 1 == c) && (c + 1 == d))
type CParser a = StateT BSC8.ByteString Maybe a
runCParser :: CParser a -> BSC8.ByteString -> Maybe (a, BSC8.ByteString)
runCParser = runStateT
{-# INLINE runCParser #-}
int :: CParser Int
int = coerce $ BSC8.readInt . BSC8.dropWhile isSpace
{-# INLINE int #-}
seqInput :: Int -> IO (VU.Vector Int)
seqInput n = VU.unfoldrN n (runCParser int) <$> BSC8.getLine
{-# INLINE seqInput #-}
timSort :: (VGM.MVector v a, Ord a) => v s a -> ST s ()
timSort = timSortBy compare
{-# INLINABLE timSort #-}
timSortBy :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> ST s ()
timSortBy cmp vec
| mr == len = iter [0] 0 (error "no merge buffer needed!")
| otherwise = VGM.unsafeNew 256 >>= iter [] 0
where
len = VGM.length vec
mr = minrun len
iter s i tmpBuf
| i >= len = performRemainingMerges s tmpBuf
| otherwise = do
(order, runLen) <- nextRun cmp vec i len
when (order == Descending) $ VGM.reverse $ VGM.unsafeSlice i runLen vec
let runEnd = min len (i + max runLen mr)
sortByBounds' cmp vec i (i + runLen) runEnd
(s', tmpBuf') <- performMerges (i : s) runEnd tmpBuf
iter s' runEnd tmpBuf'
runLengthInvariantBroken a b c i = (b - a <= i - b) || (c - b <= i - c)
performMerges [b,a] i tmpBuf
| i - b >= b - a = merge cmp vec a b i tmpBuf >>= performMerges [a] i
performMerges (c:b:a:ss) i tmpBuf
| runLengthInvariantBroken a b c i =
if i - c <= b - a
then merge cmp vec b c i tmpBuf >>= performMerges (b:a:ss) i
else do tmpBuf' <- merge cmp vec a b c tmpBuf
(ass', tmpBuf'') <- performMerges (a:ss) c tmpBuf'
performMerges (c:ass') i tmpBuf''
performMerges s _ tmpBuf = return (s, tmpBuf)
performRemainingMerges (b:a:ss) tmpBuf =
merge cmp vec a b len tmpBuf >>= performRemainingMerges (a:ss)
performRemainingMerges _ _ = return ()
{-# INLINE timSortBy #-}
sortByBounds :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> ST s ()
sortByBounds cmp a l u
| len < 2 = return ()
| len == 2 = sort2ByOffset cmp a l
| len == 3 = sort3ByOffset cmp a l
| len == 4 = sort4ByOffset cmp a l
| otherwise = sort4ByOffset cmp a l >> sortByBounds' cmp a l (l + 4) u
where
!len = u - l
{-# INLINE sortByBounds #-}
sortByBounds' :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> Int -> ST s ()
sortByBounds' cmp a l m u = _sort m
where
_sort i
| i < u = do
v <- VGM.unsafeRead a i
insert cmp a l v i
_sort (i + 1)
| otherwise = return ()
{-# INLINE sortByBounds' #-}
insert :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> a -> Int -> ST s ()
insert cmp a l = loop
where
loop val j
| j <= l = VGM.unsafeWrite a l val
| otherwise = do
e <- VGM.unsafeRead a (j - 1)
case cmp val e of
LT -> VGM.unsafeWrite a j e >> loop val (j - 1)
_ -> VGM.unsafeWrite a j val
{-# INLINE insert #-}
sort2ByOffset :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> ST s ()
sort2ByOffset cmp a off = sort2ByIndex cmp a off (off + 1)
{-# INLINABLE sort2ByOffset #-}
sort2ByIndex :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> ST s ()
sort2ByIndex cmp a i j = do
a0 <- VGM.unsafeRead a i
a1 <- VGM.unsafeRead a j
case cmp a0 a1 of
GT -> VGM.unsafeWrite a i a1 >> VGM.unsafeWrite a j a0
_ -> return ()
{-# INLINABLE sort2ByIndex #-}
sort3ByOffset :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> ST s ()
sort3ByOffset cmp a off = sort3ByIndex cmp a off (off + 1) (off + 2)
{-# INLINABLE sort3ByOffset #-}
sort3ByIndex :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> Int -> ST s ()
sort3ByIndex cmp a i j k = do
a0 <- VGM.unsafeRead a i
a1 <- VGM.unsafeRead a j
a2 <- VGM.unsafeRead a k
case cmp a0 a1 of
GT -> case cmp a0 a2 of
GT -> case cmp a2 a1 of
LT -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a k a0
_ -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a0
_ -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a0
_ -> case cmp a1 a2 of
GT -> case cmp a0 a2 of
GT -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a0
VGM.unsafeWrite a k a1
_ -> do
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a1
_ -> return ()
{-# INLINABLE sort3ByIndex #-}
sort4ByOffset :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> ST s ()
sort4ByOffset cmp a off = sort4ByIndex cmp a off (off + 1) (off + 2) (off + 3)
{-# INLINABLE sort4ByOffset #-}
sort4ByIndex :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> Int -> Int -> ST s ()
sort4ByIndex cmp a i j k l = do
a0 <- VGM.unsafeRead a i
a1 <- VGM.unsafeRead a j
a2 <- VGM.unsafeRead a k
a3 <- VGM.unsafeRead a l
case cmp a0 a1 of
GT -> case cmp a0 a2 of
GT -> case cmp a1 a2 of
GT -> case cmp a1 a3 of
GT -> case cmp a2 a3 of
GT -> do
VGM.unsafeWrite a i a3
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a1
VGM.unsafeWrite a l a0
_ -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a3
VGM.unsafeWrite a k a1
VGM.unsafeWrite a l a0
_ -> case cmp a0 a3 of
GT -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a1
VGM.unsafeWrite a k a3
VGM.unsafeWrite a l a0
_ -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a1
VGM.unsafeWrite a k a0
VGM.unsafeWrite a l a3
_ -> case cmp a2 a3 of
GT -> case cmp a1 a3 of
GT -> do
VGM.unsafeWrite a i a3
VGM.unsafeWrite a j a1
VGM.unsafeWrite a k a2
VGM.unsafeWrite a l a0
_ -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a3
VGM.unsafeWrite a k a2
VGM.unsafeWrite a l a0
_ -> case cmp a0 a3 of
GT -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a3
VGM.unsafeWrite a l a0
_ -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a0
-- VGM.unsafeWrite a l a3
_ -> case cmp a0 a3 of
GT -> case cmp a1 a3 of
GT -> do
VGM.unsafeWrite a i a3
-- VGM.unsafeWrite a j a1
VGM.unsafeWrite a k a0
VGM.unsafeWrite a l a2
_ -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a3
VGM.unsafeWrite a k a0
VGM.unsafeWrite a l a2
_ -> case cmp a2 a3 of
GT -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a0
VGM.unsafeWrite a k a3
VGM.unsafeWrite a l a2
_ -> do
VGM.unsafeWrite a i a1
VGM.unsafeWrite a j a0
-- VGM.unsafeWrite a k a2
-- VGM.unsafeWrite a l a3
_ -> case cmp a1 a2 of
GT -> case cmp a0 a2 of
GT -> case cmp a0 a3 of
GT -> case cmp a2 a3 of
GT -> do
VGM.unsafeWrite a i a3
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a0
VGM.unsafeWrite a l a1
_ -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a3
VGM.unsafeWrite a k a0
VGM.unsafeWrite a l a1
_ -> case cmp a1 a3 of
GT -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a0
VGM.unsafeWrite a k a3
VGM.unsafeWrite a l a1
_ -> do
VGM.unsafeWrite a i a2
VGM.unsafeWrite a j a0
VGM.unsafeWrite a k a1
-- VGM.unsafeWrite a l a3
_ -> case cmp a2 a3 of
GT -> case cmp a0 a3 of
GT -> do
VGM.unsafeWrite a i a3
VGM.unsafeWrite a j a0
-- VGM.unsafeWrite a k a2
VGM.unsafeWrite a l a1
_ -> do
-- VGM.unsafeWrite a i a0
VGM.unsafeWrite a j a3
-- VGM.unsafeWrite a k a2
VGM.unsafeWrite a l a1
_ -> case cmp a1 a3 of
GT -> do
-- VGM.unsafeWrite a i a0
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a3
VGM.unsafeWrite a l a1
_ -> do
-- VGM.unsafeWrite a i a0
VGM.unsafeWrite a j a2
VGM.unsafeWrite a k a1
-- VGM.unsafeWrite a l a3
_ -> case cmp a1 a3 of
GT -> case cmp a0 a3 of
GT -> do
VGM.unsafeWrite a i a3
VGM.unsafeWrite a j a0
VGM.unsafeWrite a k a1
VGM.unsafeWrite a l a2
_ -> do
-- VGM.unsafeWrite a i a0
VGM.unsafeWrite a j a3
VGM.unsafeWrite a k a1
VGM.unsafeWrite a l a2
_ -> case cmp a2 a3 of
GT -> do
-- VGM.unsafeWrite a i a0
-- VGM.unsafeWrite a j a1
VGM.unsafeWrite a k a3
VGM.unsafeWrite a l a2
_ -> do
-- VGM.unsafeWrite a i a0
-- VGM.unsafeWrite a j a1
-- VGM.unsafeWrite a k a2
-- VGM.unsafeWrite a l a3
return ()
{-# INLINABLE sort4ByIndex #-}
minrun :: Int -> Int
minrun n0 = (n0 .>>. extra) + if (lowMask .&. n0) > 0 then 1 else 0
where
!n1 = n0 .|. (n0 .>>. 1)
!n2 = n1 .|. (n1 .>>. 2)
!n3 = n2 .|. (n2 .>>. 4)
!n4 = n3 .|. (n3 .>>. 8)
!n5 = n4 .|. (n4 .>>. 16)
!n6 = n5 .|. (n5 .>>. 32)
!lowMask = n6 .>>. 6
!extra = popCount lowMask
{-# INLINE minrun #-}
data Order = Ascending | Descending deriving (Eq, Show)
nextRun :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> ST s (Order, Int)
nextRun _ _ i len | i + 1 >= len = return (Ascending, 1)
nextRun cmp vec i len = do
x <- VGM.unsafeRead vec i
y <- VGM.unsafeRead vec (i + 1)
if x `gt` y then desc y 2 else asc y 2
where
gt a b = cmp a b == GT
desc _ !k | i + k >= len = return (Descending, k)
desc x !k = do
y <- VGM.unsafeRead vec (i + k)
if x `gt` y then desc y (k + 1) else return (Descending, k)
asc _ !k | i + k >= len = return (Ascending, k)
asc x !k = do
y <- VGM.unsafeRead vec (i + k)
if x `gt` y then return (Ascending, k) else asc y (k + 1)
{-# INLINE nextRun #-}
minGallop :: Int
minGallop = 7
{-# INLINE minGallop #-}
merge :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> Int -> v s a -> ST s (v s a)
merge cmp vec l m u tmpBuf = do
vm <- VGM.unsafeRead vec m
l' <- gallopingSearchLeftPBounds (`gt` vm) vec l m
if l' >= m
then return tmpBuf
else do
vn <- VGM.unsafeRead vec (m - 1)
u' <- gallopingSearchRightPBounds (`gte` vn) vec m u
if u' <= m
then return tmpBuf
else (if (m - l') <= (u' - m) then mergeLo else mergeHi) cmp vec l' m u' tmpBuf
where
gt a b = cmp a b == GT
gte a b = cmp a b /= LT
{-# INLINE merge #-}
mergeLo :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> Int -> v s a -> ST s (v s a)
mergeLo cmp vec l m u tempBuf' = do
tmpBuf <- cloneSlice l tmpBufLen vec tempBuf'
vi <- VGM.unsafeRead tmpBuf 0
vj <- VGM.unsafeRead vec m
iter tmpBuf 0 m l vi vj minGallop minGallop
return tmpBuf
where
gt a b = cmp a b == GT
gte a b = cmp a b /= LT
tmpBufLen = m - l
finalize tmpBuf i k = do
let from = VGM.unsafeSlice i (tmpBufLen - i) tmpBuf
to = VGM.unsafeSlice k (tmpBufLen - i) vec
VGM.unsafeCopy to from
iter _ i _ _ _ _ _ _ | i >= tmpBufLen = return ()
iter tmpBuf i j k _ _ _ _ | j >= u = finalize tmpBuf i k
iter tmpBuf i j k _ vj 0 _ = do
i' <- gallopingSearchLeftPBounds (`gt` vj) tmpBuf i tmpBufLen
let gallopLen = i' - i
from = VGM.unsafeSlice i gallopLen tmpBuf
to = VGM.unsafeSlice k gallopLen vec
VGM.unsafeCopy to from
when (i' < tmpBufLen) $ do
vi' <- VGM.unsafeRead tmpBuf i'
iter tmpBuf i' j (k + gallopLen) vi' vj minGallop minGallop
iter tmpBuf i j k vi _ _ 0 = do
j' <- gallopingSearchLeftPBounds (`gte` vi) vec j u
let gallopLen = j' - j
from = VGM.slice j gallopLen vec
to = VGM.slice k gallopLen vec
VGM.unsafeMove to from
if j' >= u then finalize tmpBuf i (k + gallopLen) else do
vj' <- VGM.unsafeRead vec j'
iter tmpBuf i j' (k + gallopLen) vi vj' minGallop minGallop
iter tmpBuf i j k vi vj ga gb
| vj `gte` vi = do
VGM.unsafeWrite vec k vi
when (i + 1 < tmpBufLen) $ do
vi' <- VGM.unsafeRead tmpBuf (i + 1)
iter tmpBuf (i + 1) j (k + 1) vi' vj (ga - 1) minGallop
| otherwise = do
VGM.unsafeWrite vec k vj
if j + 1 >= u
then finalize tmpBuf i (k + 1)
else do
vj' <- VGM.unsafeRead vec (j + 1)
iter tmpBuf i (j + 1) (k + 1) vi vj' minGallop (gb - 1)
{-# INLINE mergeLo #-}
mergeHi :: VGM.MVector v a => (a -> a -> Ordering) -> v s a -> Int -> Int -> Int -> v s a -> ST s (v s a)
mergeHi cmp vec l m u tmpBuf' = do
tmpBuf <- cloneSlice m tmpBufLen vec tmpBuf'
vi <- VGM.unsafeRead vec (m - 1)
vj <- VGM.unsafeRead tmpBuf (tmpBufLen - 1)
iter tmpBuf (m - 1) (tmpBufLen - 1) (u - 1) vi vj minGallop minGallop
return tmpBuf
where
gt a b = cmp a b == GT
gte a b = cmp a b /= LT
tmpBufLen = u - m
finalize tmpBuf j = do
let from = VGM.unsafeSlice 0 (j + 1) tmpBuf
to = VGM.unsafeSlice l (j + 1) vec
VGM.unsafeCopy to from
iter _ _ j _ _ _ _ _ | j < 0 = return ()
iter tmpBuf i j _ _ _ _ _ | i < l = finalize tmpBuf j
iter tmpBuf i j k _ vj 0 _ = do
i' <- gallopingSearchRightPBounds (`gt` vj) vec l i
let gallopLen = i - i'
from = VGM.slice (i' + 1) gallopLen vec
to = VGM.slice (k - gallopLen + 1) gallopLen vec
VGM.unsafeMove to from
if i' < l
then finalize tmpBuf j
else do
vi' <- VGM.unsafeRead vec i'
iter tmpBuf i' j (k - gallopLen) vi' vj minGallop minGallop
iter tmpBuf i j k vi _ _ 0 = do
j' <- gallopingSearchRightPBounds (`gte` vi) tmpBuf 0 j
let gallopLen = j - j'
from = VGM.slice (j' + 1) gallopLen tmpBuf
to = VGM.slice (k - gallopLen + 1) gallopLen vec
VGM.unsafeCopy to from
when (j' >= 0) $ do
vj' <- VGM.unsafeRead tmpBuf j'
iter tmpBuf i j' (k - gallopLen) vi vj' minGallop minGallop
iter tmpBuf i j k vi vj ga gb
| vi `gt` vj = do
VGM.unsafeWrite vec k vi
if i - 1 < l
then finalize tmpBuf j
else do
vi' <- VGM.unsafeRead vec (i - 1)
iter tmpBuf (i - 1) j (k - 1) vi' vj (ga - 1) minGallop
| otherwise = do
VGM.unsafeWrite vec k vj
when (j - 1 >= 0) $ do
vj' <- VGM.unsafeRead tmpBuf (j - 1)
iter tmpBuf i (j - 1) (k - 1) vi vj' minGallop (gb - 1)
{-# INLINE mergeHi #-}
cloneSlice :: VGM.MVector v a => Int -> Int -> v s a -> v s a -> ST s (v s a)
cloneSlice i len vec tmpBuf = do
tmpBuf' <- ensureCapacity len tmpBuf
VGM.unsafeCopy (VGM.unsafeSlice 0 len tmpBuf') (VGM.unsafeSlice i len vec)
return tmpBuf'
{-# INLINE cloneSlice #-}
ensureCapacity :: VGM.MVector v a => Int -> v s a -> ST s (v s a)
ensureCapacity l tmpBuf
| l <= VGM.length tmpBuf = return tmpBuf
| otherwise = VGM.unsafeNew (2 * l)
{-# INLINE ensureCapacity #-}
gallopingSearchLeftPBounds :: VGM.MVector v a => (a -> Bool) -> v s a -> Int -> Int -> ST s Int
gallopingSearchLeftPBounds p vec l u
| u <= l = return l
| otherwise = do
x <- VGM.unsafeRead vec l
if p x then return l else iter (l + 1) l 2
where
binSearch = binarySearchPBounds p vec
iter !i !j !_stepSize | i >= u - 1 = do
x <- VGM.unsafeRead vec (u - 1)
if p x then binSearch (j + 1) (u - 1) else return u
iter !i !j !stepSize = do
x <- VGM.unsafeRead vec i
if p x then binSearch (j + 1) i else iter (i + stepSize) i (2 * stepSize)
{-# INLINE gallopingSearchLeftPBounds #-}
gallopingSearchRightPBounds :: VGM.MVector v a => (a -> Bool) -> v s a -> Int -> Int -> ST s Int
gallopingSearchRightPBounds p vec l u
| u <= l = return l
| otherwise = iter (u - 1) (u - 1) (-1)
where
binSearch = binarySearchPBounds p vec
iter !i !j !_stepSize | i <= l = do
x <- VGM.unsafeRead vec l
if p x then return l else binSearch (l + 1) j
iter !i !j !stepSize = do
x <- VGM.unsafeRead vec i
if p x then iter (i + stepSize) i (2 * stepSize) else binSearch (i + 1) j
{-# INLINE gallopingSearchRightPBounds #-}
binarySearchPBounds :: VGM.MVector v a => (a -> Bool) -> v s a -> Int -> Int -> ST s Int
binarySearchPBounds p vec = loop
where
loop !l !u
| u <= l = return l
| otherwise = VGM.unsafeRead vec k >>= \e -> if p e then loop l k else loop (k + 1) u
where
k = midPoint u l
{-# INLINE binarySearchPBounds #-}
midPoint :: Int -> Int -> Int
midPoint a b = toInt $ (toWord a + toWord b) `div` 2
where
toWord :: Int -> Word
toWord = fromIntegral
toInt :: Word -> Int
toInt = fromIntegral
{-# INLINE midPoint #-}
infixl 8 .<<., .>>.
(.<<.) :: Bits b => b -> Int -> b
(.<<.) = unsafeShiftL
{-# INLINE (.<<.) #-}
(.>>.) :: Bits b => b -> Int -> b
(.>>.) = unsafeShiftR
{-# INLINE (.>>.) #-}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0