Precisión de aproximaciones de pi
La precisión de una aproximación x de pi es el número de dígitos comunes entre el inicio de x y de pi. Por ejemplo, puesto que 355/113 es 3.1415929203539825 y pi es 3.141592653589793, la precisión de 355/113 es 7.
Definir las siguientes funciones
1 2 3 |
mayorPrefijoComun :: Eq a => [a] -> [a] -> [a] precisionPi :: Double -> Int precisionPiCR :: CReal -> Int |
tales que
- (mayorPrefijoComun xs ys) es el mayor prefijo común de xs e ys. Por ejemplo,
1 2 3 4 5 |
mayorPrefijoComun [] [2,3,4,5] == [] mayorPrefijoComun [2,3,5] [] == [] mayorPrefijoComun [2,3,5] [2,3,4,5] == [2,3] mayorPrefijoComun [2,3,5] [2,5,3,4] == [2] mayorPrefijoComun [2,3,5] [5,2,3,4] == [] |
- (precisionPi x) es la precisión de la aproximación de pi x. Por ejemplo,
1 2 3 4 5 6 7 8 |
precisionPi (25/8) == 2 precisionPi (22/7) == 3 precisionPi (sqrt 2 + sqrt 3) == 3 precisionPi (377/120) == 4 precisionPi (31**(1/3)) == 4 precisionPi (7^7/4^9) == 5 precisionPi (355/113) == 7 precisionPi ((2143/22)**(1/4)) == 9 |
- (precisionPiCR x) es la precisión de la aproximación de pi x, como números reales. Por ejemplo,
1 2 |
precisionPiCR (log (640320^3+744)/(sqrt 163)) == 31 precisionPiCR (log (5280^3*(236674+30303*sqrt 61)^3+744)/(sqrt 427)) == 53 |
Nota: Para la definición precisionPiCR se usa la librería Data.Number.CReal que se instala con
1 |
cabal install numbers |
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import Data.Number.CReal -- mayorPrefijoComún -- ================= -- 1ª definición mayorPrefijoComun :: Eq a => [a] -> [a] -> [a] mayorPrefijoComun [] _ = [] mayorPrefijoComun _ [] = [] mayorPrefijoComun (x:xs) (y:ys) | x == y = x : mayorPrefijoComun xs ys | otherwise = [] -- 2ª definición mayorPrefijoComun2 :: Eq a => [a] -> [a] -> [a] mayorPrefijoComun2 xs ys = [x | (x,y) <- takeWhile (\(x,y) -> x == y) (zip xs ys)] -- 3ª definición mayorPrefijoComun3 :: Eq a => [a] -> [a] -> [a] mayorPrefijoComun3 xs ys = [x | (x,y) <- takeWhile (uncurry (==)) (zip xs ys)] -- 4ª definición mayorPrefijoComun4 :: Eq a => [a] -> [a] -> [a] mayorPrefijoComun4 xs = map fst . takeWhile (uncurry (==)) . zip xs -- 5ª definición mayorPrefijoComun5 :: Eq a => [a] -> [a] -> [a] mayorPrefijoComun5 = ((map fst . takeWhile (uncurry (==))) .) . zip -- precisionPi -- =========== -- 1ª definición precisionPi :: Double -> Int precisionPi x = length (mayorPrefijoComun xs ys) - 1 where xs = show x ys = show pi -- 2ª definición precisionPi2 :: Double -> Int precisionPi2 = pred . length . mayorPrefijoComun (show pi) . show -- precisionPiCR -- ============= precisionPiCR :: CReal -> Int precisionPiCR = aux 50 where aux n x | p < n-1 = p | otherwise = aux (n+50) x where p = precisionPiCRHasta n x -- (precisionPiCRHasta n x) es la precisión de pi acotada por n. Por -- ejemplo, -- precisionPiCRHasta 1 3.14 == 2 -- precisionPiCRHasta 5 3.14 == 3 -- precisionPiCRHasta 5 3.142 == 3 -- precisionPiCRHasta 5 3.141 == 4 precisionPiCRHasta :: Int -> CReal -> Int precisionPiCRHasta n x = length (mayorPrefijoComun xs ys) - 1 where xs = showCReal n x ys = showCReal n pi |
5 Comentarios