import qualified Data.Set as S
-- 1ª solución
-- ===========
sucRecaman1 :: [Int]
sucRecaman1 = map suc1 [0..]
suc1 :: Int -> Int
suc1 0 = 0
suc1 n | y > n && y - n `notElem` ys = y - n
| otherwise = y + n
where y = suc1 (n - 1)
ys = [suc1 k | k <- [0..n - 1]]
-- 2ª solución
-- ===========
sucRecaman2 :: [Int]
sucRecaman2 = 0:zipWith3 f sucRecaman2 [1..] (repeat sucRecaman2)
where f y n ys | y > n && y - n `notElem` take n ys = y - n
| otherwise = y + n
-- 3ª solución
-- ===========
sucRecaman3 :: [Int]
sucRecaman3 = 0 : recaman (S.singleton 0) 1 0
recaman :: S.Set Int -> Int -> Int -> [Int]
recaman s n x
| x > n && (x-n) `S.notMember` s =
(x-n) : recaman (S.insert (x-n) s) (n+1) (x-n)
| otherwise =
(x+n):recaman (S.insert (x+n) s) (n+1) (x+n)
-- Comparación de eficiencia:
-- λ> sucRecaman1 !! 25
-- 17
-- (3.76 secs, 2,394,593,952 bytes)
-- λ> sucRecaman2 !! 25
-- 17
-- (0.00 secs, 0 bytes)
-- λ> sucRecaman3 !! 25
-- 17
-- (0.00 secs, 0 bytes)
--
-- λ> sucRecaman2 !! (2*10^4)
-- 14358
-- (2.69 secs, 6,927,559,784 bytes)
-- λ> sucRecaman3 !! (2*10^4)
-- 14358
-- (0.04 secs, 0 bytes)
-- Definición de invRecaman
invRecaman :: Int -> Int
invRecaman n =
length (takeWhile (/=n) sucRecaman3)
graficaSucRecaman :: Int -> IO ()
graficaSucRecaman n =
plotList [Key Nothing]
(take n sucRecaman3)
graficaInvRecaman :: Int -> IO ()
graficaInvRecaman n =
plotList [Key Nothing]
[invRecaman k | k <- [0..n]]