Ir al contenido principal

Listas duplicadas

Se observa que en la cadena "aabbccddeffgg" todos los caracteres están duplicados excepto el 'e'. Al añadirlo obtenemos la lista "aabbccddeeffgg" y se dice que esta última está duplicada.

También se observa que "aaaabbbccccdd" no está duplicada (porque hay un número impar de 'b' consecutivas). Añadiendo una 'b' se obtiene "aaaabbbbccccdd" que está duplicada.

Definir las funciones

esDuplicada :: Eq a => [a] -> Bool
duplica     :: Eq a => [a] -> [a]

tales que

  • (esDuplicada xs) se verifica si xs es una lista duplicada. Por ejemplo,
esDuplicada "aabbccddeffgg"   ==  False
esDuplicada "aabbccddeeffgg"  ==  True
esDuplicada "aaaabbbccccdd"   ==  False
esDuplicada "aaaabbbbccccdd"  ==  True
  • (duplica xs) es la lista obtenida duplicando los elementos de xs que no lo están. Por ejemplo,
duplica "b"        ==  "bb"
duplica "abba"     ==  "aabbaa"
duplica "Betis"    ==  "BBeettiiss"
duplica [1,1,1]    ==  [1,1,1,1]
duplica [1,1,1,1]  ==  [1,1,1,1]

Comprobar con QuickCheck que, para cualquier lista de enteros xs, se verifica la siguiente propiedad:

esDuplicada (duplica xs)

Soluciones

import Test.QuickCheck

esDuplicada :: Eq a => [a] -> Bool
esDuplicada []       = True
esDuplicada [_]      = False
esDuplicada (x:y:zs) = x == y && esDuplicada zs

duplica :: Eq a => [a] -> [a]
duplica []       = []
duplica [x]      = [x,x]
duplica (x:y:zs) | x == y    = x : x : duplica zs
                 | otherwise = x : x : duplica (y:zs)

prop_duplica_esDuplicada :: [Int] -> Bool
prop_duplica_esDuplicada xs =
  esDuplicada (duplica xs)

-- La comprobación es
--    λ> quickCheck prop_duplica_esDuplicada
--    +++ OK, passed 100 tests.