Dígitos de un número
Definir la función
digitos :: Integer -> [Int]
tal que digitos n
es la lista de los dígitos del número n
. Por ejemplo,
digitos 320274 == [3,2,0,2,7,4]
Soluciones
A continuación se muestran las soluciones en Haskell y las soluciones en Python.
Soluciones en Haskell
import Data.Char (digitToInt) import qualified Data.Digits as D (digits) import qualified Data.FastDigits as FD (digits) import Test.QuickCheck -- 1ª solución -- =========== digitos1 :: Integer -> [Int] digitos1 n = map fromInteger (aux n) where aux :: Integer -> [Integer] aux m | m < 10 = [m] | otherwise = aux (m `div` 10) ++ [m `rem` 10] -- 2ª solución -- =========== digitos2 :: Integer -> [Int] digitos2 n = map fromInteger (reverse (aux n)) where aux :: Integer -> [Integer] aux m | m < 10 = [m] | otherwise = (m `rem` 10) : aux (m `div` 10) -- 3ª solución -- =========== digitos3 :: Integer -> [Int] digitos3 n = map fromInteger (aux [] n) where aux :: [Integer] -> Integer -> [Integer] aux ds m | m < 10 = m : ds | otherwise = aux (m `rem` 10 : ds) (m `div` 10) -- 4ª solución -- =========== digitos4 :: Integer -> [Int] digitos4 n = [read [x] | x <- show n] -- 5ª solución -- =========== digitos5 :: Integer -> [Int] digitos5 n = map (\ x -> read [x]) (show n) -- 6ª solución -- =========== digitos6 :: Integer -> [Int] digitos6 = map (read . return) . show -- 7ª solución -- =========== digitos7 :: Integer -> [Int] digitos7 n = map digitToInt (show n) -- 8ª solución -- =========== digitos8 :: Integer -> [Int] digitos8 = map digitToInt . show -- 9ª solución -- =========== digitos9 :: Integer -> [Int] digitos9 0 = [0] digitos9 n = map fromInteger (D.digits 10 n) -- 10ª solución -- =========== digitos10 :: Integer -> [Int] digitos10 0 = [0] digitos10 n = reverse (FD.digits 10 n) -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_digitos :: NonNegative Integer -> Bool prop_digitos (NonNegative n) = all (== digitos1 n) [digitos2 n, digitos3 n, digitos4 n, digitos5 n, digitos6 n, digitos7 n, digitos8 n, digitos9 n, digitos10 n] -- La comprobación es -- λ> quickCheck prop_digitos -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- La comparación es -- λ> n = product [1..5000] -- λ> length (digitos1 n) -- 16326 -- (3.00 secs, 11,701,450,912 bytes) -- λ> length (digitos2 n) -- 16326 -- (0.13 secs, 83,393,816 bytes) -- λ> length (digitos3 n) -- 16326 -- (0.11 secs, 83,132,552 bytes) -- λ> length (digitos4 n) -- 16326 -- (0.01 secs, 23,054,920 bytes) -- λ> length (digitos5 n) -- 16326 -- (0.01 secs, 22,663,088 bytes) -- λ> length (digitos6 n) -- 16326 -- (0.06 secs, 22,663,224 bytes) -- λ> length (digitos7 n) -- 16326 -- (0.01 secs, 22,663,064 bytes) -- λ> length (digitos8 n) -- 16326 -- (0.03 secs, 22,663,192 bytes) -- λ> length (digitos9 n) -- 16326 -- (0.05 secs, 82,609,944 bytes) -- λ> length (digitos10 n) -- 16326 -- (0.01 secs, 26,295,416 bytes) -- -- λ> n = product [1..5*10^4] -- λ> length (digitos2 n) -- 213237 -- (10.17 secs, 12,143,633,056 bytes) -- λ> length (digitos3 n) -- 213237 -- (10.54 secs, 12,140,221,216 bytes) -- λ> length (digitos4 n) -- 213237 -- (1.29 secs, 2,638,199,328 bytes) -- λ> length (digitos5 n) -- 213237 -- (2.48 secs, 2,633,081,632 bytes) -- λ> length (digitos6 n) -- 213237 -- (2.59 secs, 2,633,081,600 bytes) -- λ> length (digitos7 n) -- 213237 -- (2.55 secs, 2,633,081,608 bytes) -- λ> length (digitos8 n) -- 213237 -- (2.49 secs, 2,633,081,600 bytes) -- λ> length (digitos9 n) -- 213237 -- (7.07 secs, 12,133,397,456 bytes) -- λ> length (digitos10 n) -- 213237 -- (2.47 secs, 2,725,182,064 bytes)
El código se encuentra en GitHub.
Soluciones en Python
from math import factorial from sys import setrecursionlimit from timeit import Timer, default_timer from hypothesis import given from hypothesis import strategies as st from sympy.ntheory.digits import digits setrecursionlimit(10**6) # 1ª solución # =========== def digitos1(n: int) -> list[int]: if n < 10: return [n] return digitos1(n // 10) + [n % 10] # 2ª solución # =========== def digitos2(n: int) -> list[int]: return [int(x) for x in str(n)] # 3ª solución # =========== def digitos3(n: int) -> list[int]: r: list[int] = [] for x in str(n): r.append(int(x)) return r # 4ª solución # =========== def digitos4(n: int) -> list[int]: return list(map(int, list(str(n)))) # 5ª solución # =========== def digitos5(n: int) -> list[int]: r: list[int] = [] while n > 0: r = [n % 10] + r n = n // 10 return r # 6ª solución # =========== def digitos6(n: int) -> list[int]: r: list[int] = [] while n > 0: r.append(n % 10) n = n // 10 return list(reversed(r)) # 7ª solución # =========== def digitos7(n: int) -> list[int]: return digits(n)[1:] # Comprobación de equivalencia # ============================ # La propiedad es @given(st.integers(min_value=1)) def test_digitos(n: int) -> None: r = digitos1(n) assert digitos2(n) == r assert digitos3(n) == r assert digitos4(n) == r assert digitos5(n) == r assert digitos6(n) == r assert digitos7(n) == r # La comprobación es # src> poetry run pytest -q digitos_de_un_numero.py # 1 passed in 0.49s # Comparación de eficiencia # ========================= def tiempo(ex: str) -> None: """Tiempo (en segundos) de evaluar la expresión e.""" t = Timer(ex, "", default_timer, globals()).timeit(1) print(f"{t:0.2f} segundos") # La comparación es # >>> tiempo('digitos1(factorial(6000))') # 0.58 segundos # >>> tiempo('digitos2(factorial(6000))') # 0.01 segundos # >>> tiempo('digitos3(factorial(6000))') # 0.01 segundos # >>> tiempo('digitos4(factorial(6000))') # 0.01 segundos # >>> tiempo('digitos5(factorial(6000))') # 0.60 segundos # >>> tiempo('digitos6(factorial(6000))') # 0.17 segundos # >>> tiempo('digitos7(factorial(6000))') # 0.10 segundos # # >>> tiempo('digitos2(factorial(2*10**4))') # 0.10 segundos # >>> tiempo('digitos3(factorial(2*10**4))') # 0.10 segundos # >>> tiempo('digitos4(factorial(2*10**4))') # 0.09 segundos # >>> tiempo('digitos6(factorial(2*10**4))') # 2.33 segundos # >>> tiempo('digitos7(factorial(2*10**4))') # 1.18 segundos # # >>> tiempo('digitos2(factorial(10**5))') # 3.53 segundos # >>> tiempo('digitos3(factorial(10**5))') # 3.22 segundos # >>> tiempo('digitos4(factorial(10**5))') # 3.02 segundos
El código se encuentra en GitHub.