Longitud de la parte periódica
La propiedad de la longitud de la parte periódica afirma que
Si p es un número primo distinto de 2 y de 5, entonces la longitud del período de 1/p es el menor entero positivo n tal que p divide a .
El objetivo de este ejercicio es la verificación de dicha propiedad.
Las fracciones se representan por un par de enteros. Por ejemplo, el número 2/3 se representa por (2,3). Su tipo es
1 |
type Fraccion = (Integer,Integer) |
Los números decimales se representan por ternas, donde el primer elemento es la parte entera, el segundo es el anteperíodo y el tercero es el período. Por ejemplo,
1 2 3 4 |
6/2 = 3 se representa por (3,[],[]) 1/2 = 0.5 se representa por (0,[5],[]) 1/3 = 0.333333... se representa por (0,[],[3]) 23/14 = 1.6428571428571... se representa por (1,[6],[4,2,8,5,7,1]) |
Su tipo es
1 |
type Decimal = (Integer,[Integer],[Integer]) |
Definir, usando las funciones cocientesRestos y primerRepetido de los ejercicios anteriores, las funciones
1 2 |
decimal :: Fraccion -> Decimal longitudPeriodo :: Fraccion -> Integer |
tales que
- (decimal f) es la representación decimal de la fracción f. Por ejemplo,
1 2 3 4 5 6 |
decimal (6,2) == (3,[],[]) decimal (3,4) == (0,[7,5],[]) decimal (1,3) == (0,[],[3]) decimal (23,14) == (1,[6],[4,2,8,5,7,1]) decimal (247813,19980) == (12,[4,0],[3,0,5]) decimal (1,101) == (0,[],[0,0,9,9]) |
- (longitudPeriodo f) es la longitud de la parte periódica de la representación decimal de la fracción f. Por ejemplo,
1 2 3 4 5 6 7 |
longitudPeriodo (6,2) == 0 longitudPeriodo (3,4) == 0 longitudPeriodo (1,3) == 1 longitudPeriodo (23,14) == 6 longitudPeriodo (247813,19980) == 3 longitudPeriodo (1,101) == 4 longitudPeriodo (1,1229) == 1228 |
Comprobar con QuickCheck la propiedad de la longitud de la parte periódica; es decir, k es un número natural distinto de 0 y 2 y p es el primo k-ésimo, entonces la longitud del período de 1/p es el menor entero positivo n tal que p divide a ..
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import Data.Numbers.Primes import Test.QuickCheck type Fraccion = (Integer,Integer) type Decimal = (Integer,[Integer],[Integer]) decimal :: Fraccion -> Decimal decimal (n,d) | snd y == 0 = (fst x, map fst xs, []) | otherwise = (fst x, map fst xs, map fst (y:zs)) where qrs = cocientesRestos (n,d) Just (q,r) = primerRepetido qrs (x:xs,y:ys) = break (==(q,r)) qrs zs = takeWhile (/=(q,r)) ys cocientesRestos :: Fraccion -> [(Integer,Integer)] cocientesRestos (n,d) = (q,r) : cocientesRestos (10*r, d) where (q,r) = quotRem n d primerRepetido :: Eq a => [a] -> Maybe a primerRepetido xs = aux xs [] where aux [] _ = Nothing aux (x:xs') ys | x `elem` ys = Just x | otherwise = aux xs' (x:ys) longitudPeriodo :: Fraccion -> Int longitudPeriodo (n,d) = length xs where (_,_,xs) = decimal (n,d) -- La propiedad es prop_LongitudPeriodo :: Int -> Property prop_LongitudPeriodo k = k > 0 && k /= 2 ==> longitudPeriodo (1,p) == head [n | n <- [1..], (10^n-1) `mod` p == 0] where p = primes !! k -- La comprobación es -- λ> quickCheck prop_LongitudPeriodo -- +++ OK, passed 100 tests. |
Otras soluciones
- Se pueden escribir otras soluciones en los comentarios.
- El código se debe escribir entre una línea con <pre lang=»haskell»> y otra con </pre>
Pensamiento
«En el desarrollo de la comprensión de los fenómenos complejos, la herramienta más poderosa de que dispone el intelecto humano es la abstracción. La abstracción surge del reconocimiento de las similitudes entre ciertos objetos, situaciones o procesos en el mundo real y de la decisión de concentrarse en estas similitudes e ignorar, por el momento, sus diferencias.»
*Main> quickCheck prop_Periodo
+++ OK, passed 100 tests; 5 discarded.