Definir la función
numeroDivisores :: Integer -> Integer |
tal que (numeroDivisores x)
es el número de divisores de x
. Por ejemplo,
numeroDivisores 12 == 6 numeroDivisores 25 == 3 length (show (numeroDivisores (product [1..3*10^4]))) == 1948 |
Definir la función
numeroDivisores :: Integer -> Integer |
tal que (numeroDivisores x)
es el número de divisores de x
. Por ejemplo,
numeroDivisores 12 == 6 numeroDivisores 25 == 3 length (show (numeroDivisores (product [1..3*10^4]))) == 1948 |
Se pueden generar los dígitos de Pi, como se explica en el artículo Unbounded spigot algorithms for the digits of pi c0on la función digitosPi definida por
digitosPi :: [Integer] digitosPi = g(1,0,1,1,3,3) where g (q,r,t,k,n,l) = if 4*q+r-t < n*t then n : g (10*q, 10*(r-n*t), t, k, div (10*(3*q+r)) t - 10*n, l) else g (q*k, (2*q+r)*l, t*l, k+1, div (q*(7*k+2)+r*l) (t*l), l+2) |
Por ejemplo,
λ> take 25 digitosPi [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3] |
La distribución de los primeros 25 dígitos de pi es [0,2,3,5,3,3,3,1,2,3] ya que el 0 no aparece, el 1 ocurre 2 veces, el 3 ocurre 3 veces, el 4 ocurre 5 veces, …
Usando digitosPi, definir las siguientes funciones
distribucionDigitosPi :: Int -> [Int] frecuenciaDigitosPi :: Int -> [Double] |
tales que
λ> distribucionDigitosPi 10 [0,2,1,2,1,2,1,0,0,1] λ> distribucionDigitosPi 100 [8,8,12,12,10,8,9,8,12,13] λ> distribucionDigitosPi 1000 [93,116,103,103,93,97,94,95,101,105] λ> distribucionDigitosPi 5000 [466,531,496,460,508,525,513,488,492,521] |
λ> frecuenciaDigitosPi 10 [0.0,20.0,10.0,20.0,10.0,20.0,10.0,0.0,0.0,10.0] λ> frecuenciaDigitosPi 100 [8.0,8.0,12.0,12.0,10.0,8.0,9.0,8.0,12.0,13.0] λ> frecuenciaDigitosPi 1000 [9.3,11.6,10.3,10.3,9.3,9.7,9.4,9.5,10.1,10.5] λ> frecuenciaDigitosPi 5000 [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] |
import Data.Array import Data.List (group, sort) digitosPi :: [Integer] digitosPi = g(1,0,1,1,3,3) where g (q,r,t,k,n,l) = if 4*q+r-t < n*t then n : g (10*q, 10*(r-n*t), t, k, div (10*(3*q+r)) t - 10*n, l) else g (q*k, (2*q+r)*l, t*l, k+1, div (q*(7*k+2)+r*l) (t*l), l+2) -- 1ª definición -- ============= distribucionDigitosPi :: Int -> [Int] distribucionDigitosPi n = elems (accumArray (+) 0 (0,9) [ (i,1) | i <- take n digitosPi]) frecuenciaDigitosPi :: Int -> [Double] frecuenciaDigitosPi n = [100 * (fromIntegral x / m) | x <- distribucionDigitosPi n] where m = fromIntegral n -- 2ª definición -- ============= distribucionDigitosPi2 :: Int -> [Int] distribucionDigitosPi2 n = [length xs - 1 | xs <- group (sort (take n digitosPi ++ [0..9]))] frecuenciaDigitosPi2 :: Int -> [Double] frecuenciaDigitosPi2 n = [100 * (fromIntegral x / m) | x <- distribucionDigitosPi2 n] where m = fromIntegral n -- Comparación de eficiencia -- ========================= -- λ> last (take 5000 digitosPi) -- 2 -- (4.47 secs, 3,927,848,448 bytes) -- λ> frecuenciaDigitosPi 5000 -- [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] -- (0.01 secs, 0 bytes) -- λ> frecuenciaDigitosPi2 5000 -- [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] -- (0.02 secs, 0 bytes) |
Se pueden generar los dígitos de Pi, como se explica en el artículo Unbounded spigot algorithms for the digits of pi c0on la función digitosPi definida por
digitosPi :: [Integer] digitosPi = g(1,0,1,1,3,3) where g (q,r,t,k,n,l) = if 4*q+r-t < n*t then n : g (10*q, 10*(r-n*t), t, k, div (10*(3*q+r)) t - 10*n, l) else g (q*k, (2*q+r)*l, t*l, k+1, div (q*(7*k+2)+r*l) (t*l), l+2) |
Por ejemplo,
λ> take 25 digitosPi [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3] |
La distribución de los primeros 25 dígitos de pi es [0,2,3,5,3,3,3,1,2,3] ya que el 0 no aparece, el 1 ocurre 2 veces, el 3 ocurre 3 veces, el 4 ocurre 5 veces, …
Usando digitosPi, definir las siguientes funciones
distribucionDigitosPi :: Int -> [Int] frecuenciaDigitosPi :: Int -> [Double] |
tales que
λ> distribucionDigitosPi 10 [0,2,1,2,1,2,1,0,0,1] λ> distribucionDigitosPi 100 [8,8,12,12,10,8,9,8,12,13] λ> distribucionDigitosPi 1000 [93,116,103,103,93,97,94,95,101,105] λ> distribucionDigitosPi 5000 [466,531,496,460,508,525,513,488,492,521] |
λ> frecuenciaDigitosPi 10 [0.0,20.0,10.0,20.0,10.0,20.0,10.0,0.0,0.0,10.0] λ> frecuenciaDigitosPi 100 [8.0,8.0,12.0,12.0,10.0,8.0,9.0,8.0,12.0,13.0] λ> frecuenciaDigitosPi 1000 [9.3,11.6,10.3,10.3,9.3,9.7,9.4,9.5,10.1,10.5] λ> frecuenciaDigitosPi 5000 [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] |
import Data.Array import Data.List (group, sort) digitosPi :: [Integer] digitosPi = g(1,0,1,1,3,3) where g (q,r,t,k,n,l) = if 4*q+r-t < n*t then n : g (10*q, 10*(r-n*t), t, k, div (10*(3*q+r)) t - 10*n, l) else g (q*k, (2*q+r)*l, t*l, k+1, div (q*(7*k+2)+r*l) (t*l), l+2) -- 1ª definición -- ============= distribucionDigitosPi :: Int -> [Int] distribucionDigitosPi n = elems (accumArray (+) 0 (0,9) [(i,1) | i <- take n digitosPi]) frecuenciaDigitosPi :: Int -> [Double] frecuenciaDigitosPi n = [100 * (fromIntegral x / m) | x <- distribucionDigitosPi n] where m = fromIntegral n -- 2ª definición -- ============= distribucionDigitosPi2 :: Int -> [Int] distribucionDigitosPi2 n = [length xs - 1 | xs <- group (sort (take n digitosPi ++ [0..9]))] frecuenciaDigitosPi2 :: Int -> [Double] frecuenciaDigitosPi2 n = [100 * (fromIntegral x / m) | x <- distribucionDigitosPi2 n] where m = fromIntegral n -- Comparación de eficiencia -- ========================= -- λ> last (take 5000 digitosPi) -- 2 -- (4.47 secs, 3,927,848,448 bytes) -- λ> frecuenciaDigitosPi 5000 -- [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] -- (0.01 secs, 0 bytes) -- λ> frecuenciaDigitosPi2 5000 -- [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] -- (0.02 secs, 0 bytes) |
¿Cuál es la verdad? ¿El río
que fluye y pasa
donde el barco y el barquero
son también ondas de agua?
¿O este soñar del marino
siempre con ribera y ancla?Antonio Machado
Definir las funciones
digitosIniciales :: [Int] graficaDigitosIniciales :: Int -> IO () |
tales que
λ> take 100 digitosIniciales [0,1,2,3,4,5,6,7,8,9,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9] |
import Graphics.Gnuplot.Simple -- 1ª definición -- ============= digitosIniciales :: [Int] digitosIniciales = map digitoInicial [0..] digitoInicial :: Integer -> Int digitoInicial n = read [head (show n)] -- 2ª definición -- ============= digitosIniciales2 :: [Int] digitosIniciales2 = map (read . return . head . show) [0..] -- 3ª definición -- ============= digitosIniciales3 :: [Int] digitosIniciales3 = map digitoInicial3 [0..] digitoInicial3 :: Integer -> Int digitoInicial3 = fromInteger . until (< 10) (`div` 10) -- 4ª definición -- ============= digitosIniciales4 :: [Int] digitosIniciales4 = map (fromInteger . until (< 10) (`div` 10)) [0..] -- 5ª definición -- ============= digitosIniciales5 :: [Int] digitosIniciales5 = 0 : concat [replicate k x | k <- [10^n | n <- [0..]] , x <- [1..9]] -- Comparación de eficiencia -- ========================= -- λ> digitosIniciales !! (2*10^6) -- 2 -- (0.46 secs, 320,145,984 bytes) -- λ> digitosIniciales2 !! (2*10^6) -- 2 -- (0.46 secs, 320,143,288 bytes) -- λ> digitosIniciales3 !! (2*10^6) -- 2 -- (0.17 secs, 320,139,216 bytes) -- λ> digitosIniciales4 !! (2*10^6) -- 2 -- (0.55 secs, 320,139,248 bytes) -- λ> digitosIniciales5 !! (2*10^6) -- 2 -- (0.12 secs, 224,158,992 bytes) graficaDigitosIniciales :: Int -> IO () graficaDigitosIniciales n = plotList [ Key Nothing , Title ("graficaDigitosIniciales " ++ show n) , PNG ("Digitos_iniciales_" ++ show n ++ ".png" ) ] (take n digitosIniciales) |
Se pueden generar los dígitos de Pi, como se explica en el artículo Unbounded spigot algorithms for the digits of pi, con la función digitosPi definida por
digitosPi :: [Integer] digitosPi = g(1,0,1,1,3,3) where g (q,r,t,k,n,l) = if 4*q+r-t < n*t then n : g (10*q, 10*(r-n*t), t, k, div (10*(3*q+r)) t - 10*n, l) else g (q*k, (2*q+r)*l, t*l, k+1, div (q*(7*k+2)+r*l) (t*l), l+2) |
Por ejemplo,
λ> take 25 digitosPi [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3] |
La distribución de los primeros 25 dígitos de pi es [0,2,3,5,3,3,3,1,2,3] ya que el 0 no aparece, el 1 ocurre 2 veces, el 3 ocurre 3 veces, el 4 ocurre 5 veces, …
Usando digitosPi, definir las siguientes funciones
distribucionDigitosPi :: Int -> [Int] frecuenciaDigitosPi :: Int -> [Double] |
tales que
λ> distribucionDigitosPi 10 [0,2,1,2,1,2,1,0,0,1] λ> distribucionDigitosPi 100 [8,8,12,12,10,8,9,8,12,13] λ> distribucionDigitosPi 1000 [93,116,103,103,93,97,94,95,101,105] λ> distribucionDigitosPi 5000 [466,531,496,460,508,525,513,488,492,521] |
λ> frecuenciaDigitosPi 10 [0.0,20.0,10.0,20.0,10.0,20.0,10.0,0.0,0.0,10.0] λ> frecuenciaDigitosPi 100 [8.0,8.0,12.0,12.0,10.0,8.0,9.0,8.0,12.0,13.0] λ> frecuenciaDigitosPi 1000 [9.3,11.6,10.3,10.3,9.3,9.7,9.4,9.5,10.1,10.5] λ> frecuenciaDigitosPi 5000 [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] |
import Data.Array import Data.List (group, sort) digitosPi :: [Integer] digitosPi = g(1,0,1,1,3,3) where g (q,r,t,k,n,l) = if 4*q+r-t < n*t then n : g (10*q, 10*(r-n*t), t, k, div (10*(3*q+r)) t - 10*n, l) else g (q*k, (2*q+r)*l, t*l, k+1, div (q*(7*k+2)+r*l) (t*l), l+2) -- 1ª definición -- ============= distribucionDigitosPi :: Int -> [Int] distribucionDigitosPi n = elems (accumArray (+) 0 (0,9) [(i,1) | i <- take n digitosPi]) frecuenciaDigitosPi :: Int -> [Double] frecuenciaDigitosPi n = [100 * (fromIntegral x / m) | x <- distribucionDigitosPi n] where m = fromIntegral n -- 2ª definición -- ============= distribucionDigitosPi2 :: Int -> [Int] distribucionDigitosPi2 n = [length xs - 1 | xs <- group (sort (take n digitosPi ++ [0..9]))] frecuenciaDigitosPi2 :: Int -> [Double] frecuenciaDigitosPi2 n = [100 * (fromIntegral x / m) | x <- distribucionDigitosPi2 n] where m = fromIntegral n -- Comparación de eficiencia -- ========================= -- λ> last (take 5000 digitosPi) -- 2 -- (4.47 secs, 3,927,848,448 bytes) -- λ> frecuenciaDigitosPi 5000 -- [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] -- (0.01 secs, 0 bytes) -- λ> frecuenciaDigitosPi2 5000 -- [9.32,10.62,9.92,9.2,10.16,10.5,10.26,9.76,9.84,10.42] -- (0.02 secs, 0 bytes) |