Menu Close

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

   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,
     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,
     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,
     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

   cabal install numbers

Soluciones

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 soluciones de “Precisión de aproximaciones de pi

  1. enrnarbej
    import Data.Number.CReal
     
    mayorPrefijoComun :: Eq a => [a] -> [a] -> [a]
    mayorPrefijoComun xs ys =
      (map fst . takeWhile ((x,y) -> x == y) . zip xs) ys
     
    precisionPi :: Double -> Int
    precisionPi p =
      (length . mayorPrefijoComun (show pi) . show) p - 1
     
    precisionPiCR :: CReal -> Int
    precisionPiCR p =
      (length . mayorPrefijoComun (showCReal 1000 pi) . showCReal 1000) p - 1
  2. albcercid
    import Data.Number.CReal
     
    mayorPrefijoComun :: Eq a => [a] -> [a] -> [a]
    mayorPrefijoComun [] ys = []
    mayorPrefijoComun xs [] = []
    mayorPrefijoComun (x:xs) (y:ys)
      | x == y    = x : mayorPrefijoComun xs ys
      | otherwise = []
     
    precisionPi :: Double -> Int
    precisionPi x =
      length (mayorPrefijoComun (show x) (show pi)) - 1
     
    precisionPiCR :: CReal -> Int
    precisionPiCR = aux 100
      where
        aux n x | n == p    = aux (n+100) x
                | otherwise = p
          where
            p = length (mayorPrefijoComun (showCReal n x) (showCReal n pi)) - 1
  3. marlobrip
    import Data.Number.CReal 
     
    mayorPrefijoComun :: Eq a => [a] -> [a] -> [a]
    mayorPrefijoComun (x:xs) (y:ys)
      | x == y    = x : mayorPrefijoComun xs ys
      | otherwise = []
    mayorPrefijoComun _ _ = []
     
    precisionPi :: Double -> Int
    precisionPi x =
      length (mayorPrefijoComun (show x) (show pi)) - 1
     
    precisionPiCR  :: CReal -> Int
    precisionPiCR x =
      length (mayorPrefijoComun (d x) (d pi)) - 1
      where d = showCReal 1000
  4. eliguivil
    import Data.Number.CReal
     
    mayorPrefijoComun :: Eq a => [a] -> [a] -> [a]
    mayorPrefijoComun (x:xs) (y:ys) | x == y = x : mayorPrefijoComun xs ys
                                    | otherwise = []
    mayorPrefijoComun _ _ = []
     
    precisionPi :: Double -> Int
    precisionPi n = length $ mayorPrefijoComun (f $ show n)
                                               (f $ showCReal (length $ show n) (pi ::CReal))
      where
        f = delete '.'
     
    precisionPiCR :: CReal -> Int
    precisionPiCR = aux 1
      where
        aux n k | mayorPrefijoComun a b == a = aux (n+1) k
                | otherwise = length a
          where
            a = showCReal n k
            b = showCReal n pi
  5. cescarde
    import Data.Number.CReal
     
    mayorPrefijoComun :: Eq a => [a] -> [a] -> [a]
    mayorPrefijoComun [] _ = []
    mayorPrefijoComun _ [] = []
    mayorPrefijoComun (x:xs) (y:ys) | x == y    = x : mayorPrefijoComun xs ys
                                    | otherwise = []
     
    precisionPi :: Double -> Int
    precisionPi n = length $ mayorPrefijoComun (f $ show n) (f $ show pi)
                where f = delete '.'
     
    precisionPiCR :: CReal -> Int
    precisionPiCR n = length $ mayorPrefijoComun (f $ g n) (f $ g pi)
                where f = delete '.'
                      g = showCReal 1000

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.