import Data.List (sort)
import Data.Numbers.Primes (isPrime)
-- 1ª definición
-- =============
cadenasDivisores :: Int -> [[Int]]
cadenasDivisores n = sort (extiendeLista [[n]])
where extiendeLista [] = []
extiendeLista ((1:xs):yss) = xs : extiendeLista yss
extiendeLista ((x:xs):yss) =
extiendeLista ([y:x:xs | y <- divisores x] ++ yss)
-- (divisores x) es la lista decreciente de los divisores de x distintos
-- de x. Por ejemplo,
-- divisores 12 == [6,4,3,2,1]
divisores :: Int -> [Int]
divisores x =
[y | y <- [a,a-1..1], x `mod` y == 0]
where a = x `div` 2
-- 2ª definición
-- =============
cadenasDivisores2 :: Int -> [[Int]]
cadenasDivisores2 = sort . aux
where aux 1 = [[]]
aux n = [xs ++ [n] | xs <- concatMap aux (divisores n)]
-- 3ª definición
-- =============
cadenasDivisores3 :: Int -> [[Int]]
cadenasDivisores3 = sort . map reverse . aux
where aux 1 = [[]]
aux n = map (n:) (concatMap aux (divisores3 n))
-- (divisores3 x) es la lista creciente de los divisores de x distintos
-- de x. Por ejemplo,
-- divisores3 12 == [1,2,3,4,6]
divisores3 :: Int -> [Int]
divisores3 x =
[y | y <- [1..a], x `mod` y == 0]
where a = x `div` 2
-- 1ª definición de nCadenasDivisores
-- ==================================
nCadenasDivisores1 :: Int -> Int
nCadenasDivisores1 = length . cadenasDivisores
-- 2ª definición de nCadenasDivisores
-- ==================================
nCadenasDivisores2 :: Int -> Int
nCadenasDivisores2 1 = 1
nCadenasDivisores2 n =
sum [nCadenasDivisores2 x | x <- divisores n]