Mayúsculas iniciales
Se consideran las siguientes reglas de mayúsculas iniciales para los títulos:
- la primera palabra comienza en mayúscula y
- todas las palabras que tienen 4 letras como mínimo empiezan con mayúsculas
Definir la función
titulo :: [String] -> [String]
tal que titulo ps
es la lista de las palabras de ps
con las reglas de mayúsculas iniciales de los títulos. Por ejemplo,
λ> titulo ["eL","arTE","DE","La","proGraMacion"] ["El","Arte","de","la","Programacion"]
Soluciones
A continuación se muestran las soluciones en Haskell y las soluciones en Python.
Soluciones en Haskell
import Data.Char (toUpper, toLower) import Test.QuickCheck -- 1ª solución -- =========== titulo1 :: [String] -> [String] titulo1 [] = [] titulo1 (p:ps) = mayusculaInicial p : [transforma q | q <- ps] -- (mayusculaInicial xs) es la palabra xs con la letra inicial -- en mayúscula y las restantes en minúsculas. Por ejemplo, -- mayusculaInicial "sEviLLa" == "Sevilla" mayusculaInicial :: String -> String mayusculaInicial [] = [] mayusculaInicial (x:xs) = toUpper x : [toLower y | y <- xs] -- (transforma p) es la palabra p con mayúscula inicial si su longitud -- es mayor o igual que 4 y es p en minúscula en caso contrario transforma :: String -> String transforma p | length p >= 4 = mayusculaInicial p | otherwise = minuscula p -- (minuscula xs) es la palabra xs en minúscula. minuscula :: String -> String minuscula xs = [toLower x | x <- xs] -- 2ª solución -- =========== titulo2 :: [String] -> [String] titulo2 [] = [] titulo2 (p:ps) = mayusculaInicial p : aux ps where aux [] = [] aux (q:qs) = transforma q : aux qs -- 3ª solución -- =========== titulo3 :: [String] -> [String] titulo3 [] = [] titulo3 (p:ps) = mayusculaInicial p : map transforma ps -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_titulo :: [String] -> Bool prop_titulo xs = all (== titulo1 xs) [titulo2 xs, titulo3 xs] -- La comprobación es -- λ> quickCheck prop_titulo -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> length (titulo1 (take (10^7) (cycle ["hOy","Es","juEves","dE","Noviembre"]))) -- 10000000 -- (2.17 secs, 1,680,592,512 bytes) -- λ> length (titulo2 (take (10^7) (cycle ["hOy","Es","juEves","dE","Noviembre"]))) -- 10000000 -- (2.45 secs, 2,240,592,464 bytes) -- λ> length (titulo3 (take (10^7) (cycle ["hOy","Es","juEves","dE","Noviembre"]))) -- 10000000 -- (0.16 secs, 1,440,592,464 bytes)
Soluciones en Python
from sys import setrecursionlimit from timeit import Timer, default_timer from hypothesis import given from hypothesis import strategies as st setrecursionlimit(10**6) # 1ª solución # =========== # (mayusculaInicial xs) es la palabra xs con la letra inicial # en mayúscula y las restantes en minúsculas. Por ejemplo, # mayusculaInicial("sEviLLa") == "Sevilla" def mayusculaInicial(xs: str) -> str: return xs.capitalize() # (minuscula xs) es la palabra xs en minúscula. def minuscula(xs: str) -> str: return xs.lower() # (transforma p) es la palabra p con mayúscula inicial si su longitud # es mayor o igual que 4 y es p en minúscula en caso contrario def transforma(p: str) -> str: if len(p) >= 4: return mayusculaInicial(p) return minuscula(p) def titulo1(ps: list[str]) -> list[str]: if ps: return [mayusculaInicial(ps[0])] + [transforma(q) for q in ps[1:]] return [] # 2ª solución # =========== def titulo2(ps: list[str]) -> list[str]: def aux(qs: list[str]) -> list[str]: if qs: return [transforma(qs[0])] + aux(qs[1:]) return [] if ps: return [mayusculaInicial(ps[0])] + aux(ps[1:]) return [] # 3ª solución # =========== def titulo3(ps: list[str]) -> list[str]: if ps: return [mayusculaInicial(ps[0])] + list(map(transforma, ps[1:])) return [] # Comprobación de equivalencia # ============================ # La propiedad es @given(st.lists(st.text())) def test_titulo(ps: list[str]) -> None: r = titulo1(ps) assert titulo2(ps) == r assert titulo3(ps) == r # La comprobación es # src> poetry run pytest -q mayusculas_iniciales.py # 1 passed in 0.55s # Comparación de eficiencia # ========================= def tiempo(e: str) -> None: """Tiempo (en segundos) de evaluar la expresión e.""" t = Timer(e, "", default_timer, globals()).timeit(1) print(f"{t:0.2f} segundos") # La comparación es # >>> tiempo('len(mayusculaInicial1("aB"*(10**7)))') # >>> tiempo('titulo1(["eL","arTE","DE","La","proGraMacion "]*1900)') # 0.00 segundos # >>> tiempo('titulo2(["eL","arTE","DE","La","proGraMacion "]*1900)') # 0.30 segundos # >>> tiempo('titulo3(["eL","arTE","DE","La","proGraMacion "]*1900)') # 0.00 segundos # # >>> tiempo('titulo1(["eL","arTE","DE","La","proGraMacion "]*(2*10**6))') # 2.93 segundos # >>> tiempo('titulo3(["eL","arTE","DE","La","proGraMacion "]*(2*10**6))') # 2.35 segundos