module RandomCycle.List.Partition where
import Control.Monad (guard)
import Data.Bits
import GHC.Natural (Natural)
import System.Random.Stateful
spanBits :: (Bool -> Bool) -> Natural -> [a] -> ([a], (Natural, [a]))
spanBits :: forall a. (Bool -> Bool) -> Natural -> [a] -> ([a], (Natural, [a]))
spanBits Bool -> Bool
_ Natural
bs xs :: [a]
xs@[] = ([a]
xs, (Natural
bs, [a]
xs))
spanBits Bool -> Bool
switch Natural
bs (a
x : [a]
xs)
| Bool -> Bool
switch (Natural
bs forall a. Bits a => a -> Int -> Bool
`testBit` Int
0) = let ([a]
zs, (Natural
bs', [a]
zzs)) = forall a. (Bool -> Bool) -> Natural -> [a] -> ([a], (Natural, [a]))
spanBits Bool -> Bool
switch (Natural
bs forall a. Bits a => a -> Int -> a
`shiftR` Int
1) [a]
xs in (a
x forall a. a -> [a] -> [a]
: [a]
zs, (Natural
bs', [a]
zzs))
| Bool
otherwise = ([], (Natural
bs, a
x forall a. a -> [a] -> [a]
: [a]
xs))
partitionFromBits :: Natural -> [a] -> [[a]]
partitionFromBits :: forall a. Natural -> [a] -> [[a]]
partitionFromBits Natural
_ [] = []
partitionFromBits Natural
bs [a]
xs =
let switch :: Bool -> Bool
switch = if Natural
bs forall a. Bits a => a -> Int -> Bool
`testBit` Int
0 then forall a. a -> a
id else Bool -> Bool
not
([a]
ys, (Natural
bs', [a]
yss)) = forall a. (Bool -> Bool) -> Natural -> [a] -> ([a], (Natural, [a]))
spanBits Bool -> Bool
switch Natural
bs [a]
xs
in [a]
ys forall a. a -> [a] -> [a]
: forall a. Natural -> [a] -> [[a]]
partitionFromBits Natural
bs' [a]
yss
partitionLengths :: Word -> Int -> [Int]
partitionLengths :: Word -> Int -> [Int]
partitionLengths Word
bs = forall {b}. FiniteBits b => b -> Int -> Int -> [Int]
op Word
bs (forall b. FiniteBits b => b -> Int
countTrailingZeros Word
bs)
where
op :: b -> Int -> Int -> [Int]
op b
b Int
0 Int
m = let b' :: b
b' = forall a. Bits a => a -> a
complement b
b in b -> Int -> Int -> [Int]
op b
b' (forall b. FiniteBits b => b -> Int
countTrailingZeros b
b') Int
m
op b
b Int
z Int
m =
if Int
z forall a. Ord a => a -> a -> Bool
> Int
m
then [Int
m | Int
m forall a. Ord a => a -> a -> Bool
> Int
0]
else
let b' :: b
b' = b
b forall a. Bits a => a -> Int -> a
`shiftR` Int
z
in Int
z forall a. a -> [a] -> [a]
: b -> Int -> Int -> [Int]
op b
b' (forall b. FiniteBits b => b -> Int
countTrailingZeros b
b') (Int
m forall a. Num a => a -> a -> a
- Int
z)
partitionFromBitsThin :: ([a] -> Bool) -> Natural -> [a] -> Maybe [[a]]
partitionFromBitsThin :: forall a. ([a] -> Bool) -> Natural -> [a] -> Maybe [[a]]
partitionFromBitsThin [a] -> Bool
_ Natural
_ [] = forall a. a -> Maybe a
Just []
partitionFromBitsThin [a] -> Bool
r Natural
bs [a]
xs =
let ps :: [[a]]
ps = forall a. Natural -> [a] -> [[a]]
partitionFromBits Natural
bs [a]
xs
in forall (f :: * -> *). Alternative f => Bool -> f ()
guard (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [a] -> Bool
r [[a]]
ps) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure [[a]]
ps
uniformPartitionThinN ::
(StatefulGen g m) =>
Int ->
Int ->
([a] -> Bool) ->
[a] ->
g ->
m (Maybe [[a]])
uniformPartitionThinN :: forall g (m :: * -> *) a.
StatefulGen g m =>
Int -> Int -> ([a] -> Bool) -> [a] -> g -> m (Maybe [[a]])
uniformPartitionThinN Int
maxit Int
_ [a] -> Bool
_ [a]
_ g
_ | Int
maxit forall a. Ord a => a -> a -> Bool
<= Int
0 = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
uniformPartitionThinN Int
maxit Int
n [a] -> Bool
r [a]
xs g
g = do
Natural
bs <- forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Natural
0, Natural
2 forall a b. (Num a, Integral b) => a -> b -> a
^ Int
n forall a. Num a => a -> a -> a
- Natural
1) g
g
case forall a. ([a] -> Bool) -> Natural -> [a] -> Maybe [[a]]
partitionFromBitsThin [a] -> Bool
r Natural
bs [a]
xs of
Maybe [[a]]
Nothing -> forall g (m :: * -> *) a.
StatefulGen g m =>
Int -> Int -> ([a] -> Bool) -> [a] -> g -> m (Maybe [[a]])
uniformPartitionThinN (Int
maxit forall a. Num a => a -> a -> a
- Int
1) Int
n [a] -> Bool
r [a]
xs g
g
Just [[a]]
ys -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just [[a]]
ys
uniformPartition :: (StatefulGen g m) => [a] -> g -> m [[a]]
uniformPartition :: forall g (m :: * -> *) a. StatefulGen g m => [a] -> g -> m [[a]]
uniformPartition [a]
xs g
g = do
let d :: Int
d = forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs
Natural
bs <- forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
uniformRM (Natural
0, Natural
2 forall a b. (Num a, Integral b) => a -> b -> a
^ Int
d forall a. Num a => a -> a -> a
- Natural
1) g
g
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Natural -> [a] -> [[a]]
partitionFromBits Natural
bs [a]
xs
uniformPartitionThin ::
(StatefulGen g m) =>
Int ->
([a] -> Bool) ->
[a] ->
g ->
m (Maybe [[a]])
uniformPartitionThin :: forall g (m :: * -> *) a.
StatefulGen g m =>
Int -> ([a] -> Bool) -> [a] -> g -> m (Maybe [[a]])
uniformPartitionThin Int
maxit [a] -> Bool
r [a]
xs = forall g (m :: * -> *) a.
StatefulGen g m =>
Int -> Int -> ([a] -> Bool) -> [a] -> g -> m (Maybe [[a]])
uniformPartitionThinN Int
maxit (forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs) [a] -> Bool
r [a]
xs