tal que (numeros cs) es la lista de los números enteros no negativos de la cadena cs. Por ejemplo,
λ> numeros "Esta cadena tiene 3 numeros: el 16 y el 2019 solamente."
[3,16,2019]
λ> numeros "Esta cadena tiene 3 numeros naturales: -2 más 2 es 0"
[3,2,0]
λ> numeros "Esta cadena tiene 1 numero natural: 2.5 no es entereo"
[1]
λ> numeros "Esta cadena tiene 3 numeros: el 16 y el 2019 solamente."
[3,16,2019]
λ> numeros "Esta cadena tiene 3 numeros naturales: -2 más 2 es 0"
[3,2,0]
λ> numeros "Esta cadena tiene 1 numero natural: 2.5 no es entereo"
[1]
Soluciones
import Data.Char(isDigit)-- 1ª definición-- =============
numeros ::String->[Int]
numeros cs =mapread(filter esNumero (words cs))-- (esNumero cs) se verifica si la cadena no vacía cs representa-- un número entero. Por ejemplo,-- esNumero "2019" == True-- esNumero "20.9" == False-- esNumero "201a" == False
esNumero ::String->Bool
esNumero =all(`elem` ['0'..'9'])-- 2ª solución-- ===========
numeros2 ::String->[Int]
numeros2 cs =mapread(filter(all isDigit)(words cs))-- 3ª solución-- ===========
numeros3 ::String->[Int]
numeros3 =mapread . filter(all isDigit) . words
import Data.Char (isDigit)
-- 1ª definición
-- =============
numeros :: String -> [Int]
numeros cs = map read (filter esNumero (words cs))
-- (esNumero cs) se verifica si la cadena no vacía cs representa
-- un número entero. Por ejemplo,
-- esNumero "2019" == True
-- esNumero "20.9" == False
-- esNumero "201a" == False
esNumero :: String -> Bool
esNumero = all (`elem` ['0'..'9'])
-- 2ª solución
-- ===========
numeros2 :: String -> [Int]
numeros2 cs = map read (filter (all isDigit) (words cs))
-- 3ª solución
-- ===========
numeros3 :: String -> [Int]
numeros3 = map read . filter (all isDigit) . words
Pensamiento
Tu profecía, poeta.
— Mañana hablarán los mudos:
el corazón y la piedra.
Una familia de conjuntos es estable por uniones si la unión de dos conjuntos cualesquiera de la familia pertenece a la familia. Por ejemplo, {∅, {1}, {2}, {1,2}, {1,3}, {1,2,3}} es estable por uniones; pero {{1}, {2}, {1,3}, {1,2,3}} no lo es.
La conjetura afirma que toda familia no vacía estable por uniones y distinta de {∅} posee algún elemento que pertenece al menos a la mitad de los conjuntos de la familia.
Definir las funciones
esEstable :: Ord a => Set (Set a) -> Bool
familiasEstables :: Ord a => Set a -> Set (Set (Set a))
mayoritarios :: Ord a => Set (Set a) -> [a]
conjeturaFrankl :: Int -> Bool
esEstable :: Ord a => Set (Set a) -> Bool
familiasEstables :: Ord a => Set a -> Set (Set (Set a))
mayoritarios :: Ord a => Set (Set a) -> [a]
conjeturaFrankl :: Int -> Bool
tales que
(esEstable f) se verifica si la familia f es estable por uniones. Por ejemplo,
(conjeturaFrankl n) se verifica si para toda familia f formada por elementos del conjunto {1,2,…,n} no vacía, estable por uniones y distinta de {∅} posee algún elemento que pertenece al menos a la mitad de los conjuntos de f. Por ejemplo.
import Data.Set as S ( Set
, delete
, deleteFindMin
, empty
, filter
, fromList
, insert
, map
, member
, null
, singleton
, size
, toList
, union
, unions
)import Data.List as L (filter
, null)
esEstable ::Ord a => Set (Set a)->Bool
esEstable xss =and[ys `S.union` zs `member` xss |(ys,yss)<- selecciones xss
, zs <- toList yss]-- (seleccciones xs) es la lista de los pares formada por un elemento de-- xs y los restantes elementos. Por ejemplo,-- λ> selecciones (fromList [3,2,5])-- [(2,fromList [3,5]),(3,fromList [2,5]),(5,fromList [2,3])]
selecciones ::Ord a => Set a ->[(a,Set a)]
selecciones xs =[(x,delete x xs)| x <- toList xs]
familiasEstables ::Ord a => Set a -> Set (Set (Set a))
familiasEstables xss =
S.filter esEstable (familias xss)-- (familias c) es la familia formadas con elementos de c. Por ejemplo,-- λ> mapM_ print (familias (fromList [1,2]))-- fromList []-- fromList [fromList []]-- fromList [fromList [],fromList [1]]-- fromList [fromList [],fromList [1],fromList [1,2]]-- fromList [fromList [],fromList [1],fromList [1,2],fromList [2]]-- fromList [fromList [],fromList [1],fromList [2]]-- fromList [fromList [],fromList [1,2]]-- fromList [fromList [],fromList [1,2],fromList [2]]-- fromList [fromList [],fromList [2]]-- fromList [fromList [1]]-- fromList [fromList [1],fromList [1,2]]-- fromList [fromList [1],fromList [1,2],fromList [2]]-- fromList [fromList [1],fromList [2]]-- fromList [fromList [1,2]]-- fromList [fromList [1,2],fromList [2]]-- fromList [fromList [2]]-- λ> size (familias (fromList [1,2]))-- 16-- λ> size (familias (fromList [1,2,3]))-- 256-- λ> size (familias (fromList [1,2,3,4]))-- 65536
familias ::Ord a => Set a -> Set (Set (Set a))
familias c =
subconjuntos (subconjuntos c)-- (subconjuntos c) es el conjunto de los subconjuntos de c. Por ejemplo,-- λ> mapM_ print (subconjuntos (fromList [1,2,3]))-- fromList []-- fromList [1]-- fromList [1,2]-- fromList [1,2,3]-- fromList [1,3]-- fromList [2]-- fromList [2,3]-- fromList [3]
subconjuntos ::Ord a => Set a -> Set (Set a)
subconjuntos c
| S.null c = singleton empty
|otherwise= S.map(insert x) sr `union` sr
where(x,rc)= deleteFindMin c
sr = subconjuntos rc
-- (elementosFamilia f) es el conjunto de los elementos de los elementos-- de la familia f. Por ejemplo, -- λ> elementosFamilia (fromList [empty, fromList [1,2], fromList [2,5]])-- fromList [1,2,5]
elementosFamilia ::Ord a => Set (Set a)-> Set a
elementosFamilia = unions . toList
-- (nOcurrencias f x) es el número de conjuntos de la familia f a los-- que pertenece el elemento x. Por ejemplo,-- nOcurrencias (fromList [empty, fromList [1,3], fromList [3,5]]) 3 == 2-- nOcurrencias (fromList [empty, fromList [1,3], fromList [3,5]]) 4 == 0-- nOcurrencias (fromList [empty, fromList [1,3], fromList [3,5]]) 5 == 1
nOcurrencias ::Ord a => Set (Set a)-> a ->Int
nOcurrencias f x =length(L.filter(x `member`)(toList f))
mayoritarios ::Ord a => Set (Set a)->[a]
mayoritarios f =[x | x <- toList (elementosFamilia f)
, nOcurrencias f x >= n]where n =(1+ size f) `div` 2
conjeturaFrankl ::Int->Bool
conjeturaFrankl n =and[not(L.null(mayoritarios f))| f <- fs
, f /= fromList []
, f /= fromList [empty]]where fs = toList (familiasEstables (fromList [1..n]))-- conjeturaFrankl' :: Int -> Bool
conjeturaFrankl' n =[f | f <- fs
, L.null(mayoritarios f)
, f /= fromList []
, f /= fromList [empty]]where fs = toList (familiasEstables (fromList [1..n]))
import Data.Set as S ( Set
, delete
, deleteFindMin
, empty
, filter
, fromList
, insert
, map
, member
, null
, singleton
, size
, toList
, union
, unions
)
import Data.List as L ( filter
, null
)
esEstable :: Ord a => Set (Set a) -> Bool
esEstable xss =
and [ys `S.union` zs `member` xss | (ys,yss) <- selecciones xss
, zs <- toList yss]
-- (seleccciones xs) es la lista de los pares formada por un elemento de
-- xs y los restantes elementos. Por ejemplo,
-- λ> selecciones (fromList [3,2,5])
-- [(2,fromList [3,5]),(3,fromList [2,5]),(5,fromList [2,3])]
selecciones :: Ord a => Set a -> [(a,Set a)]
selecciones xs =
[(x,delete x xs) | x <- toList xs]
familiasEstables :: Ord a => Set a -> Set (Set (Set a))
familiasEstables xss =
S.filter esEstable (familias xss)
-- (familias c) es la familia formadas con elementos de c. Por ejemplo,
-- λ> mapM_ print (familias (fromList [1,2]))
-- fromList []
-- fromList [fromList []]
-- fromList [fromList [],fromList [1]]
-- fromList [fromList [],fromList [1],fromList [1,2]]
-- fromList [fromList [],fromList [1],fromList [1,2],fromList [2]]
-- fromList [fromList [],fromList [1],fromList [2]]
-- fromList [fromList [],fromList [1,2]]
-- fromList [fromList [],fromList [1,2],fromList [2]]
-- fromList [fromList [],fromList [2]]
-- fromList [fromList [1]]
-- fromList [fromList [1],fromList [1,2]]
-- fromList [fromList [1],fromList [1,2],fromList [2]]
-- fromList [fromList [1],fromList [2]]
-- fromList [fromList [1,2]]
-- fromList [fromList [1,2],fromList [2]]
-- fromList [fromList [2]]
-- λ> size (familias (fromList [1,2]))
-- 16
-- λ> size (familias (fromList [1,2,3]))
-- 256
-- λ> size (familias (fromList [1,2,3,4]))
-- 65536
familias :: Ord a => Set a -> Set (Set (Set a))
familias c =
subconjuntos (subconjuntos c)
-- (subconjuntos c) es el conjunto de los subconjuntos de c. Por ejemplo,
-- λ> mapM_ print (subconjuntos (fromList [1,2,3]))
-- fromList []
-- fromList [1]
-- fromList [1,2]
-- fromList [1,2,3]
-- fromList [1,3]
-- fromList [2]
-- fromList [2,3]
-- fromList [3]
subconjuntos :: Ord a => Set a -> Set (Set a)
subconjuntos c
| S.null c = singleton empty
| otherwise = S.map (insert x) sr `union` sr
where (x,rc) = deleteFindMin c
sr = subconjuntos rc
-- (elementosFamilia f) es el conjunto de los elementos de los elementos
-- de la familia f. Por ejemplo,
-- λ> elementosFamilia (fromList [empty, fromList [1,2], fromList [2,5]])
-- fromList [1,2,5]
elementosFamilia :: Ord a => Set (Set a) -> Set a
elementosFamilia = unions . toList
-- (nOcurrencias f x) es el número de conjuntos de la familia f a los
-- que pertenece el elemento x. Por ejemplo,
-- nOcurrencias (fromList [empty, fromList [1,3], fromList [3,5]]) 3 == 2
-- nOcurrencias (fromList [empty, fromList [1,3], fromList [3,5]]) 4 == 0
-- nOcurrencias (fromList [empty, fromList [1,3], fromList [3,5]]) 5 == 1
nOcurrencias :: Ord a => Set (Set a) -> a -> Int
nOcurrencias f x =
length (L.filter (x `member`) (toList f))
mayoritarios :: Ord a => Set (Set a) -> [a]
mayoritarios f =
[x | x <- toList (elementosFamilia f)
, nOcurrencias f x >= n]
where n = (1 + size f) `div` 2
conjeturaFrankl :: Int -> Bool
conjeturaFrankl n =
and [ not (L.null (mayoritarios f))
| f <- fs
, f /= fromList []
, f /= fromList [empty]]
where fs = toList (familiasEstables (fromList [1..n]))
-- conjeturaFrankl' :: Int -> Bool
conjeturaFrankl' n =
[f | f <- fs
, L.null (mayoritarios f)
, f /= fromList []
, f /= fromList [empty]]
where fs = toList (familiasEstables (fromList [1..n]))
Pensamiento
Pero tampoco es razón
desdeñar
consejo que es confesión.
se pueden calcular el número pi con la precisión que se desee. Por ejemplo,
λ> import Data.Number.CReal
λ> showCReal 60 pi
"3.141592653589793238462643383279502884197169399375105820974945"
λ> import Data.Number.CReal
λ> showCReal 60 pi
"3.141592653589793238462643383279502884197169399375105820974945"
importa la librería y calcula el número pi con 60 decimales.
La distribución de las diferencias de los dígitos consecutivos para los 18 primeros n dígitos de pi se calcula como sigue: los primeros 18 dígitos de pi son
(graficas ns f) dibuja en el fichero f las gráficas de las distribuciones de las diferencias de los dígitos consecutivos para los primeros n dígitos de pi, para n en ns. Por ejemplo, al evaluar (graficas [100,250..4000] “distribucionDDCpi.png” se escribe en el fichero “distribucionDDCpi.png” la siguiente gráfica
Soluciones
import Data.Number.CReal
import Graphics.Gnuplot.Simple
import Data.Array
-- λ> digitosPi 18-- [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3]
digitosPi ::Int->[Int]
digitosPi n =init[read[c]| c <-(x:xs)]where(x:_:xs)= showCReal n pi-- λ> diferenciasConsecutivos (digitosPi 18)-- [2,-3,3,-4,-4,7,-4,1,2,-2,-3,-1,2,-2,6,1,-1]
diferenciasConsecutivos ::Num a =>[a]->[a]
diferenciasConsecutivos xs =zipWith(-) xs (tail xs)
distribucionDDCpi ::Int->[Int]
distribucionDDCpi =
distribucion . diferenciasConsecutivos . digitosPi
where distribucion xs =
elems (accumArray (+)0(-9,9)(zip xs (repeat1)))
graficas ::[Int]-> FilePath ->IO()
graficas ns f =
plotLists [Key Nothing, PNG f][puntos n | n <- ns]where puntos ::Int->[(Int,Int)]
puntos n =zip[-9..9](distribucionDDCpi n)
import Data.Number.CReal
import Graphics.Gnuplot.Simple
import Data.Array
-- λ> digitosPi 18
-- [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3]
digitosPi :: Int -> [Int]
digitosPi n = init [read [c] | c <- (x:xs)]
where (x:_:xs) = showCReal n pi
-- λ> diferenciasConsecutivos (digitosPi 18)
-- [2,-3,3,-4,-4,7,-4,1,2,-2,-3,-1,2,-2,6,1,-1]
diferenciasConsecutivos :: Num a => [a] -> [a]
diferenciasConsecutivos xs =
zipWith (-) xs (tail xs)
distribucionDDCpi :: Int -> [Int]
distribucionDDCpi =
distribucion . diferenciasConsecutivos . digitosPi
where distribucion xs =
elems (accumArray (+) 0 (-9,9) (zip xs (repeat 1)))
graficas :: [Int] -> FilePath -> IO ()
graficas ns f =
plotLists [Key Nothing, PNG f]
[puntos n | n <- ns]
where puntos :: Int -> [(Int,Int)]
puntos n = zip [-9..9] (distribucionDDCpi n)
Pensamiento
Doy consejo, a fuer de viejo:
nunca sigas mi consejo.
digitosPi ::[Integer]
digitosPi = g(1,0,1,1,3,3)where
g (q,r,t,k,n,l)=if4*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)
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]
λ> 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]
distribucionDigitosPi :: Int -> [Int]
frecuenciaDigitosPi :: Int -> [Double]
tales que
(distribucionDigitosPi n) es la distribución de los n primeros dígitos de pi. Por ejemplo,
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)=if4*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)
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)
Pensamiento
¿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?
Un número de Aquiles es un número natural n que es potente (es decir, si p es un divisor primo de n, entonces p² también lo es) y no es una potencia perfecta (es decir, no existen números naturales m y k tales que n es igual a m^k). Por ejemplo,
108 es un número de Aquiles proque es un número potente (ya que su factorización es 2^2 · 3^3, sus divisores primos son 2 and 3 y sus cuadrados (2^2 = 4 y 3^2 = 9) son divisores de 108. Además, 108 no es una potencia perfecta.
360 no es un número de Aquiles ya que 5 es un divisor primo de 360, pero 5^2 = 15 no lo es.
784 no es un número de Aquiles porque, aunque es potente, es una potencia perfecta ya que 784 = 28^2.
huecosDeAquiles es la sucesión de la diferencias entre los números de Aquiles consecutivos. Por ejemplo,
λ> take 15 huecosDeAquiles
[36,92,88,104,40,68,148,27,125,64,104,4,153,27,171]
λ> take 15 huecosDeAquiles
[36,92,88,104,40,68,148,27,125,64,104,4,153,27,171]
(graficaHuecosDeAquiles n) dibuja la gráfica de los n primeros huecos de Aquiles. Por ejemplo, (graficaHuecosDeAquiles 160) dibuja
Soluciones
import Data.List (group)import Data.Numbers.Primes (primeFactors)import Graphics.Gnuplot.Simple
-- Definición de esAquiles-- =======================
esAquiles ::Integer->Bool
esAquiles x = esPotente x && noEsPotenciaPerfecta x
-- (esPotente x) se verifica si x es potente. Por ejemplo,-- esPotente 108 == True-- esPotente 360 == False-- esPotente 784 == True
esPotente ::Integer->Bool
esPotente x =all(>1)(exponentes x)-- (exponentes x) es la lista de los exponentes en la factorización de-- x. Por ejemplo,-- exponentes 108 == [2,3]-- exponentes 360 == [3,2,1]-- exponentes 784 == [4,2]
exponentes ::Integer->[Int]
exponentes x =maplength(group (primeFactors x))-- (noEsPotenciaPerfecta x) se verifica si x no es una potencia-- perfecta. Por ejemplo,-- noEsPotenciaPerfecta 108 == True-- noEsPotenciaPerfecta 360 == True-- noEsPotenciaPerfecta 784 == False
noEsPotenciaPerfecta ::Integer->Bool
noEsPotenciaPerfecta x =foldl1gcd(exponentes x)==1-- Definición de huecosDeAquiles-- =============================
huecosDeAquiles ::[Integer]
huecosDeAquiles =zipWith(-)(tail aquiles) aquiles
-- aquiles es la sucesión de los números de Aquiles. Por ejemplo, -- λ> take 15 aquiles-- [72,108,200,288,392,432,500,648,675,800,864,968,972,1125,1152]
aquiles ::[Integer]
aquiles =filter esAquiles [2..]-- Definición de graficaHuecosDeAquiles-- ====================================
graficaHuecosDeAquiles ::Int->IO()
graficaHuecosDeAquiles n =
plotList [ Key Nothing
, PNG "Huecos_de_Aquiles.png"](take n huecosDeAquiles)
import Data.List (group)
import Data.Numbers.Primes (primeFactors)
import Graphics.Gnuplot.Simple
-- Definición de esAquiles
-- =======================
esAquiles :: Integer -> Bool
esAquiles x = esPotente x && noEsPotenciaPerfecta x
-- (esPotente x) se verifica si x es potente. Por ejemplo,
-- esPotente 108 == True
-- esPotente 360 == False
-- esPotente 784 == True
esPotente :: Integer -> Bool
esPotente x = all (>1) (exponentes x)
-- (exponentes x) es la lista de los exponentes en la factorización de
-- x. Por ejemplo,
-- exponentes 108 == [2,3]
-- exponentes 360 == [3,2,1]
-- exponentes 784 == [4,2]
exponentes :: Integer -> [Int]
exponentes x = map length (group (primeFactors x))
-- (noEsPotenciaPerfecta x) se verifica si x no es una potencia
-- perfecta. Por ejemplo,
-- noEsPotenciaPerfecta 108 == True
-- noEsPotenciaPerfecta 360 == True
-- noEsPotenciaPerfecta 784 == False
noEsPotenciaPerfecta :: Integer -> Bool
noEsPotenciaPerfecta x = foldl1 gcd (exponentes x) == 1
-- Definición de huecosDeAquiles
-- =============================
huecosDeAquiles :: [Integer]
huecosDeAquiles = zipWith (-) (tail aquiles) aquiles
-- aquiles es la sucesión de los números de Aquiles. Por ejemplo,
-- λ> take 15 aquiles
-- [72,108,200,288,392,432,500,648,675,800,864,968,972,1125,1152]
aquiles :: [Integer]
aquiles = filter esAquiles [2..]
-- Definición de graficaHuecosDeAquiles
-- ====================================
graficaHuecosDeAquiles :: Int -> IO ()
graficaHuecosDeAquiles n =
plotList [ Key Nothing
, PNG "Huecos_de_Aquiles.png"
]
(take n huecosDeAquiles)
Pensamiento
Tengo a mis amigos
en mi soledad;
cuando estoy con ellos
¡qué lejos están!