import Data.List (genericLength)
-- 1ª solución
-- ===========
nNumerosConFactorialesDivisibles :: Integer -> Integer -> Integer
nNumerosConFactorialesDivisibles x y =
genericLength (numerosConFactorialesDivisibles x y)
-- (numerosConFactorialesDivisibles x y) es la lista de números
-- divisibles por el factorial de x pero no divisibles por el
-- factorial de y. Por ejemplo,
-- numerosConFactorialesDivisibles 2 5 == [2,3,4]
-- numerosConFactorialesDivisibles 15 25 == [5,6,7,8,9]
numerosConFactorialesDivisibles :: Integer -> Integer -> [Integer]
numerosConFactorialesDivisibles x y =
[z | z <- [0..y-1]
, factorial z `mod` x == 0
, factorial z `mod` y /= 0]
-- (factorial n) es el factorial de n. Por ejemplo,
-- factorial 4 == 24
factorial :: Integer -> Integer
factorial n = product [1..n]
-- 2ª solución (usando la función de Smarandache)
-- ==============================================
nNumerosConFactorialesDivisibles2 :: Integer -> Integer -> Integer
nNumerosConFactorialesDivisibles2 x y =
max 0 (smarandache y - smarandache x)
--(smarandache n) es el menor número cuyo factorial es divisible por
-- n. Por ejemplo,
-- smarandache 8 == 4
-- smarandache 10 == 5
-- smarandache 16 == 6
smarandache :: Integer -> Integer
smarandache x =
head [n | (n,y) <- zip [0..] factoriales
, y `mod` x == 0]
-- factoriales es la lista de los factoriales. Por ejemplo,
-- λ> take 12 factoriales
-- [1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800]
factoriales :: [Integer]
factoriales = 1 : scanl1 (*) [1..]
-- Comparación de eficiencia
-- λ> nNumerosConFactorialesDivisibles 100 2000
-- 5
-- (2.70 secs, 3,933,938,648 bytes)
-- λ> nNumerosConFactorialesDivisibles2 100 2000
-- 5
-- (0.01 secs, 148,200 bytes)