Enumeración de conjuntos finitos de naturales
Los conjuntos finitos de números naturales se pueden enumerar como sigue
0: [] 1: [0] 2: [1] 3: [1,0] 4: [2] 5: [2,0] 6: [2,1] 7: [2,1,0] 8: [3] 9: [3,0] 10: [3,1] 11: [3,1,0] 12: [3,2] 13: [3,2,0] 14: [3,2,1] 15: [3,2,1,0] 16: [4] 17: [4,0] 18: [4,1] 19: [4,1,0]
en la que los elementos están ordenados de manera decreciente.
Definir la constante
enumeracionCFN :: [[Integer]]
tal que sus elementos son los conjuntos de los números naturales con la ordenación descrita anteriormente. Por ejemplo,
λ> take 20 enumeracionCFN [[], [0], [1],[1,0], [2],[2,0],[2,1],[2,1,0], [3],[3,0],[3,1],[3,1,0],[3,2],[3,2,0],[3,2,1],[3,2,1,0], [4],[4,0],[4,1],[4,1,0]]
Comprobar con QuickCheck que
- si (xs,ys) es un par de elementos consecutivos de enumeracionCFN, entonces xs < ys;
- todo conjunto finito de números naturales, representado por una lista decreciente, está en enumeracionCFN.
Soluciones
import Data.List (genericLength, nub, sort) import Test.QuickCheck 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] -- La primera propiedad es prop_enumeracionCFN :: Int -> Property prop_enumeracionCFN n = n >= 0 ==> xs < ys where (xs:ys:_) = drop n enumeracionCFN -- La comprobación es -- λ> quickCheck prop_enumeracionCFN -- +++ OK, passed 100 tests. -- La segunda propiedad es prop_completa :: [Integer] -> Bool prop_completa xs = xs' `elem` enumeracionCFN where xs' = reverse (sort (nub (map abs xs))) -- La comprobación es -- λ> quickCheckWith (stdArgs {maxSize=15}) prop_completa -- +++ OK, passed 100 tests.