История изменений
Исправление nezamudich, (текущая версия) :
Наговнякал, не приходя в сознание:
type GenState = (Int, Int)
genNext :: Int -> Int -> Int -> GenState -> GenState
genNext a b m (xn, xn') = let xn'' = (a * xn + b * xn') `mod` m
in xn'' `seq` (xn', xn'')
floyd :: Eq a => (a -> a) -> a -> (Int, a)
floyd f x0 = z `seq` (go2 (f z) 1, z)
where
z = go1 (f x0) (f (f x0))
go1 x y | x == y = x
| otherwise = go1 (f x) (f (f y))
go2 x n | x == z = n
| otherwise = go2 (f x) (n + 1)
main :: IO ()
main = do
let a = 2
b = 3
m = 23
x0 = (1, 1)
print . fst $ floyd (genNext a b m) x0 -- Output: 176
Думаю, на списках было бы идиоматичнее сделать. Но, как сделал, так сделал.
Исходная версия nezamudich, :
Наговнякал, не приходя в сознание:
type GenState = (Int, Int)
genNext :: Int -> Int -> Int -> GenState -> GenState
genNext a b m (xn, xn') = let xn'' = (a * xn + b * xn') `mod` m
in xn'' `seq` (xn', xn'')
genSeed :: Int -> Int -> GenState
genSeed = (,)
genExtract :: GenState -> Int
genExtract = fst
floyd :: Eq a => (a -> a) -> a -> (Int, a)
floyd f x0 = z `seq` (go2 (f z) 1, z)
where
z = go1 (f x0) (f (f x0))
go1 x y | x == y = x
| otherwise = go1 (f x) (f (f y))
go2 x n | x == z = n
| otherwise = go2 (f x) (n + 1)
main :: IO ()
main = do
let a = 2
b = 3
m = 23
x0 = (1, 1)
print . fst $ floyd (genNext a b m) x0 -- Output: 176
Думаю, на списках было бы идиоматичнее сделать. Но, как сделал, так сделал.