import Data.List (tails, nub, sort)
-- 1ª solución
-- ===========
-- (sumas xs) es el conjunto de las sumas de pares de elementos de
-- xs. Por ejemplo,
-- sumas2 [0,2,3,4] == [0,2,3,4,5,6,7,8]
sumas :: [Integer] -> [Integer]
sumas xs = nub [x + y | x <- xs, y <- xs]
-- (restas xs) es el conjunto de las restas de pares de elementos de
-- xs. Por ejemplo,
-- restas [0,2,3,4] == [0,-2,-3,-4,2,-1,3,1,4]
restas :: [Integer] -> [Integer]
restas xs = nub [x - y | x <- xs, y <- xs]
tieneMSQR :: [Integer] -> Bool
tieneMSQR xs = length (sumas xs) > length (restas xs)
conjuntosMSQR :: [[Integer]]
conjuntosMSQR = [xs | xs <- enumeracionCFN, tieneMSQR xs]
-- enumeracionCFN es la enumeración de los conjuntos finitos de números
-- naturales del ejercicio anterior.
enumeracionCFN :: [[Integer]]
enumeracionCFN = concatMap enumeracionCFNHasta [0..]
-- (enumeracionCFNHasta n) es la lista de conjuntos con la enumeración
-- anterior cuyo primer elemento es n. Por ejemplo,
-- λ> enumeracionCFNHasta 1
-- [[1],[1,0]]
-- λ> enumeracionCFNHasta 2
-- [[2],[2,0],[2,1],[2,1,0]]
-- λ> enumeracionCFNHasta 3
-- [[3],[3,0],[3,1],[3,1,0],[3,2],[3,2,0],[3,2,1],[3,2,1,0]]
enumeracionCFNHasta :: Integer -> [[Integer]]
enumeracionCFNHasta 0 = [[],[0]]
enumeracionCFNHasta n =
[n:xs | k <- [0..n-1], xs <- enumeracionCFNHasta k]
-- 2ª solución
-- ===========
-- (sumas2 xs) es el conjunto de las sumas de pares de elementos de
-- xs. Por ejemplo,
-- sumas2 [0,2,3,4] == [0,2,3,4,5,6,7,8]
-- sumas2 [0,2,3,4] == [0,2,3,4,5,6,7,8]
sumas2 :: [Integer] -> [Integer]
sumas2 xs = nub [x + y | (x:ys) <- tails xs, y <- (x:ys)]
-- (restas2 xs) es el conjunto de las restas de pares de elementos de
-- xs. Por ejemplo,
-- sumas2 [0,2,3,4] == [0,2,3,4,5,6,7,8]
-- restas2 [0,2,3,4] == [0,-2,-3,-4,2,-1,3,1,4]
restas2 :: [Integer] -> [Integer]
restas2 xs = 0 : ys ++ map negate ys
where ys = nub [x - y | (x:ys) <- tails (sort xs), y <- ys]
tieneMSQR2 :: [Integer] -> Bool
tieneMSQR2 xs = length (sumas2 xs) > length (restas2 xs)
conjuntosMSQR2 :: [[Integer]]
conjuntosMSQR2 = [xs | xs <- enumeracionCFN, tieneMSQR2 xs]
-- Comparación de eficiencia
-- =========================
-- λ> length (takeWhile (< [17,16..0]) conjuntosMSQR)
-- 66
-- (21.36 secs, 10,301,222,168 bytes)
-- λ> length (takeWhile (< [17,16..0]) conjuntosMSQR2)
-- 66
-- (10.13 secs, 7,088,969,752 bytes) |