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] |
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"] |
λ> 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) |
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 |
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