Suma de los dígitos de una cadena
Definir la función
sumaDigitos :: String -> Int
tal que sumaDigitos xs' es la suma de los dígitos de la cadena
xs`. Por ejemplo,
sumaDigitos "SE 2431 X" == 10
Soluciones
A continuación se muestran las soluciones en Haskell y las soluciones en Python.
Soluciones en Haskell
import Data.Char (digitToInt, isDigit) import Test.QuickCheck -- 1ª solución -- =========== sumaDigitos1 :: String -> Int sumaDigitos1 xs = sum [digitToInt x | x <- xs, isDigit x] -- 2ª solución -- =========== sumaDigitos2 :: String -> Int sumaDigitos2 [] = 0 sumaDigitos2 (x:xs) | isDigit x = digitToInt x + sumaDigitos2 xs | otherwise = sumaDigitos2 xs -- 3ª solución -- =========== sumaDigitos3 :: String -> Int sumaDigitos3 xs = sum (map digitToInt (filter isDigit xs)) -- 4ª solución -- =========== sumaDigitos4 :: String -> Int sumaDigitos4 = sum . map digitToInt . filter isDigit -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_sumaDigitos :: String -> Bool prop_sumaDigitos xs = all (== sumaDigitos1 xs) [sumaDigitos2 xs, sumaDigitos3 xs, sumaDigitos4 xs] -- La comprobación es -- λ> quickCheck prop_sumaDigitos -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> sumaDigitos1 (take (4*10^6) (cycle "ab12")) -- 3000000 -- (1.92 secs, 819,045,328 bytes) -- λ> sumaDigitos2 (take (4*10^6) (cycle "ab12")) -- 3000000 -- (1.79 secs, 856,419,112 bytes) -- λ> sumaDigitos3 (take (4*10^6) (cycle "ab12")) -- 3000000 -- (0.62 secs, 723,045,296 bytes) -- λ> sumaDigitos4 (take (4*10^6) (cycle "ab12")) -- 3000000 -- (0.63 secs, 723,045,552 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 # =========== def sumaDigitos1(xs: str) -> int: return sum((int(x) for x in xs if x.isdigit())) # 2ª solución # =========== def sumaDigitos2(xs: str) -> int: if xs: if xs[0].isdigit(): return int(xs[0]) + sumaDigitos2(xs[1:]) return sumaDigitos2(xs[1:]) return 0 # 3ª solución # =========== def sumaDigitos3(xs: str) -> int: r = 0 for x in xs: if x.isdigit(): r = r + int(x) return r # Comprobación de equivalencia # ============================ # La propiedad es @given(st.text()) def test_sumaDigitos(xs: str) -> None: r = sumaDigitos1(xs) assert sumaDigitos2(xs) == r assert sumaDigitos3(xs) == r # La comprobación es # src> poetry run pytest -q suma_de_digitos_de_cadena.py # 1 passed in 0.41s # 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('mayorExponente1(2, 2**(2*10**4))') # Comparación de eficiencia # ========================= # # La comparación es # >>> tiempo('sumaDigitos1("ab12"*5000)') # 0.00 segundos # >>> tiempo('sumaDigitos2("ab12"*5000)') # 0.02 segundos # >>> tiempo('sumaDigitos3("ab12"*5000)') # 0.00 segundos # # >>> tiempo('sumaDigitos1("ab12"*(5*10**6))') # 1.60 segundos # >>> tiempo('sumaDigitos3("ab12"*(5*10**6))') # 1.83 segundos