{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
module AtCoder.Extra.Monoid.RollingHash
(
RollingHash (..),
new,
unsafeNew,
)
where
import Data.Vector.Generic qualified as VG
import Data.Vector.Generic.Mutable qualified as VGM
import Data.Vector.Unboxed qualified as VU
import Data.Vector.Unboxed.Mutable qualified as VUM
import GHC.Exts (proxy#)
import GHC.TypeNats (KnownNat, natVal')
data RollingHash b p = RollingHash
{
forall {k} {k} (b :: k) (p :: k). RollingHash b p -> Int
hashRH :: {-# UNPACK #-} !Int,
forall {k} {k} (b :: k) (p :: k). RollingHash b p -> Int
nextDigitRH :: {-# UNPACK #-} !Int
}
deriving
(
RollingHash b p -> RollingHash b p -> Bool
(RollingHash b p -> RollingHash b p -> Bool)
-> (RollingHash b p -> RollingHash b p -> Bool)
-> Eq (RollingHash b p)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (b :: k) k (p :: k).
RollingHash b p -> RollingHash b p -> Bool
$c== :: forall k (b :: k) k (p :: k).
RollingHash b p -> RollingHash b p -> Bool
== :: RollingHash b p -> RollingHash b p -> Bool
$c/= :: forall k (b :: k) k (p :: k).
RollingHash b p -> RollingHash b p -> Bool
/= :: RollingHash b p -> RollingHash b p -> Bool
Eq,
Int -> RollingHash b p -> ShowS
[RollingHash b p] -> ShowS
RollingHash b p -> String
(Int -> RollingHash b p -> ShowS)
-> (RollingHash b p -> String)
-> ([RollingHash b p] -> ShowS)
-> Show (RollingHash b p)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (b :: k) k (p :: k). Int -> RollingHash b p -> ShowS
forall k (b :: k) k (p :: k). [RollingHash b p] -> ShowS
forall k (b :: k) k (p :: k). RollingHash b p -> String
$cshowsPrec :: forall k (b :: k) k (p :: k). Int -> RollingHash b p -> ShowS
showsPrec :: Int -> RollingHash b p -> ShowS
$cshow :: forall k (b :: k) k (p :: k). RollingHash b p -> String
show :: RollingHash b p -> String
$cshowList :: forall k (b :: k) k (p :: k). [RollingHash b p] -> ShowS
showList :: [RollingHash b p] -> ShowS
Show
)
{-# INLINE new #-}
new :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p
new :: forall (b :: Nat) (p :: Nat).
(KnownNat b, KnownNat p) =>
Int -> RollingHash b p
new Int
h = Int -> Int -> RollingHash b p
forall {k} {k} (b :: k) (p :: k). Int -> Int -> RollingHash b p
RollingHash (Int
h Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy# p -> Nat
forall (n :: Nat). KnownNat n => Proxy# n -> Nat
natVal' (forall (a :: Nat). Proxy# a
forall {k} (a :: k). Proxy# a
proxy# @p))) (Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy# b -> Nat
forall (n :: Nat). KnownNat n => Proxy# n -> Nat
natVal' (forall (a :: Nat). Proxy# a
forall {k} (a :: k). Proxy# a
proxy# @b)))
{-# INLINE unsafeNew #-}
unsafeNew :: forall b p. (KnownNat b, KnownNat p) => Int -> RollingHash b p
unsafeNew :: forall (b :: Nat) (p :: Nat).
(KnownNat b, KnownNat p) =>
Int -> RollingHash b p
unsafeNew Int
h = Int -> Int -> RollingHash b p
forall {k} {k} (b :: k) (p :: k). Int -> Int -> RollingHash b p
RollingHash Int
h (Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy# b -> Nat
forall (n :: Nat). KnownNat n => Proxy# n -> Nat
natVal' (forall (a :: Nat). Proxy# a
forall {k} (a :: k). Proxy# a
proxy# @b)))
instance (KnownNat b, KnownNat p) => Semigroup (RollingHash b p) where
{-# INLINE (<>) #-}
(RollingHash !Int
digit1 !Int
hash1) <> :: RollingHash b p -> RollingHash b p -> RollingHash b p
<> (RollingHash !Int
digit2 !Int
hash2) = Int -> Int -> RollingHash b p
forall {k} {k} (b :: k) (p :: k). Int -> Int -> RollingHash b p
RollingHash Int
digit' Int
hash'
where
!p :: Int
p = Nat -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Nat -> Int) -> Nat -> Int
forall a b. (a -> b) -> a -> b
$ Proxy# p -> Nat
forall (n :: Nat). KnownNat n => Proxy# n -> Nat
natVal' (forall (a :: Nat). Proxy# a
forall {k} (a :: k). Proxy# a
proxy# @p)
!digit' :: Int
digit' = Int
digit1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
digit2 Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
p
!hash' :: Int
hash' = (Int
hash1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
digit2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
hash2) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
p
instance (KnownNat b, KnownNat p) => Monoid (RollingHash b p) where
{-# INLINE mempty #-}
mempty :: RollingHash b p
mempty = Int -> Int -> RollingHash b p
forall {k} {k} (b :: k) (p :: k). Int -> Int -> RollingHash b p
RollingHash Int
1 Int
0
type RHRepr = (Int, Int)
instance VU.IsoUnbox (RollingHash b p) RHRepr where
{-# INLINE toURepr #-}
toURepr :: RollingHash b p -> RHRepr
toURepr (RollingHash Int
a Int
b) = (Int
a, Int
b)
{-# INLINE fromURepr #-}
fromURepr :: RHRepr -> RollingHash b p
fromURepr (!Int
a, !Int
b) = Int -> Int -> RollingHash b p
forall {k} {k} (b :: k) (p :: k). Int -> Int -> RollingHash b p
RollingHash Int
a Int
b
newtype instance VU.MVector s (RollingHash b p) = MV_RH (VUM.MVector s RHRepr)
newtype instance VU.Vector (RollingHash b p) = V_RH (VU.Vector RHRepr)
deriving via (RollingHash b p `VU.As` RHRepr) instance VGM.MVector VUM.MVector (RollingHash b p)
deriving via (RollingHash b p `VU.As` RHRepr) instance VG.Vector VU.Vector (RollingHash b p)
instance VU.Unbox (RollingHash b p)