Pseudo-random numbers/PCG32: Difference between revisions

→‎{{header|Haskell}}: added solution
No edit summary
(→‎{{header|Haskell}}: added solution)
Line 794:
4 : 20005
</pre>
 
=={{header|Haskell}}==
 
Implement given algorithm as an instance of <code>RandomGen</code> class.
 
<lang haskell>import Data.Bits
import Data.Word
import System.Random
import Data.List
 
data PCGen = PCGen !Word64 !Word64
 
mkPCGen state sequence =
let
n = 6364136223846793005 :: Word64
inc = (sequence `shiftL` 1) .|. 1 :: Word64
in PCGen ((inc + state)*n + inc) inc
 
instance RandomGen PCGen where
next (PCGen state inc) =
let
n = 6364136223846793005 :: Word64
xs = fromIntegral $ ((state `shiftR` 18) `xor` state) `shiftR` 27 :: Word32
rot = fromIntegral $ state `shiftR` 59 :: Int
in (fromIntegral $ (xs `shiftR` rot) .|. (xs `shiftL` ((-rot) .&. 31))
, PCGen (state * n + inc) inc)
 
split _ = error "PCG32 is not splittable"
 
randoms' :: RandomGen g => g -> [Int]
randoms' g = unfoldr (pure . next) g
 
toFloat n = fromIntegral n / (2^32 - 1)</lang>
 
Direct usage of generator:
<pre>*Main> take 5 $ randoms' (mkPCGen 42 54)
[2707161783,2068313097,3122475824,2211639955,3215226955]
 
*Main> let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5) . toFloat) <$> (randoms' (mkPCGen 987654321 1))
[20049,20022,20115,19809,20005]</pre>
 
Using <code>Random</code> class gives different results due to internal shuffling:
<pre>*Main> take 5 $ randoms (mkPCGen 42 54)
[2068313097,2211639955,3421331566,2167406445,4181216144]
 
*Main>let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5)) <$> (randoms (mkPCGen 987654321 1) :: [Float])
[20009,20065,20023,19876,20027]</pre>
 
=={{header|Java}}==
Anonymous user