Menu Close

Raíz cúbica entera

Un número x es un cubo si existe un y tal que x = y^3. Por ejemplo, 8 es un cubo porque 8 = 2^3.

Definir la función

   raizCubicaEntera :: Integer -> Maybe Integer.

tal que (raizCubicaEntera x n) es justo la raíz cúbica del número natural x, si x es un cubo y Nothing en caso contrario. Por ejemplo,

   raizCubicaEntera 8             ==  Just 2
   raizCubicaEntera 9             ==  Nothing
   raizCubicaEntera 27            ==  Just 3
   raizCubicaEntera 64            ==  Just 4
   raizCubicaEntera (2^30)        ==  Just 1024
   raizCubicaEntera (10^9000)     ==  Just (10^3000)
   raizCubicaEntera (5 + 10^9000) ==  Nothing

Soluciones

import Test.QuickCheck
 
-- 1ª definición
-- =============
 
raizCubicaEntera :: Integer -> Maybe Integer
raizCubicaEntera x = aux 0
  where aux y | y^3 > x   = Nothing
              | y^3 == x  = Just y
              | otherwise = aux (y+1)
 
-- 2ª definición
-- =============
 
raizCubicaEntera2 :: Integer -> Maybe Integer
raizCubicaEntera2 x 
  | y^3 == x  = Just y
  | otherwise = Nothing
  where (y:_) = dropWhile (\y -> y^3 < x) [0..]
 
-- 3ª definición
-- =============
 
raizCubicaEntera3 :: Integer -> Maybe Integer 
raizCubicaEntera3 1 = Just 1
raizCubicaEntera3 x = aux (0,x)
    where aux (a,b) | d == x    = Just c
                    | c == a    = Nothing
                    | d < x     = aux (c,b)
                    | otherwise = aux (a,c) 
              where c = (a+b) `div` 2
                    d = c^3
 
-- 4ª definición
-- =============
 
raizCubicaEntera4 :: Integer -> Maybe Integer
raizCubicaEntera4 x 
  | y^3 == x  = Just y
  | otherwise = Nothing
  where y = floor ((fromIntegral x)**(1 / 3))
 
-- Nota. La definición anterior falla para números grandes. Por ejemplo,
--    λ> raizCubicaEntera4 (2^30)
--    Nothing
--    λ> raizCubicaEntera (2^30)
--    Just 1024
 
-- Equivalencia
-- ============
 
-- La propiedad es                        
prop_raizCubicaEntera :: Integer -> Property
prop_raizCubicaEntera x =
  x >= 0 ==>
  and [raizCubicaEntera x == f x | f <- [ raizCubicaEntera2
                                        , raizCubicaEntera3]]
 
-- La comprobación es              
--    λ> quickCheck prop_raizCubicaEntera
--    +++ OK, passed 100 tests.
 
-- Comparación de eficiencia
-- =========================
 
--    λ> raizCubicaEntera (10^18)
--    Just 1000000
--    (1.80 secs, 1,496,137,192 bytes)
--    λ> raizCubicaEntera2 (10^18)
--    Just 1000000
--    (0.71 secs, 712,134,128 bytes)
--    λ> raizCubicaEntera3 (10^18)
--    Just 1000000
--    (0.01 secs, 196,424 bytes)
--
--    λ> raizCubicaEntera2 (5^27)
--    Just 1953125
--    (1.42 secs, 1,390,760,920 bytes)
--    λ> raizCubicaEntera3 (5^27)
--    Just 1953125
--    (0.00 secs, 195,888 bytes)
--
--    λ> raizCubicaEntera3 (10^9000) == Just (10^3000)
--    True
--    (2.05 secs, 420,941,368 bytes)
--    λ> raizCubicaEntera3 (5 + 10^9000) == Nothing
--    True
--    (2.08 secs, 420,957,576 bytes)

Pensamiento

Tras el vivir y el soñar,
está lo que más importa:
despertar.

Antonio Machado

Avanzado

3 soluciones de “Raíz cúbica entera

  1. luipromor
    import Math.NumberTheory.Powers.Cubes (exactCubeRoot)
     
    raizCubicaEntera1 :: Integer -> Maybe Integer
    raizCubicaEntera1 x = exactCubeRoot x
     
    raizCubicaEntera2 :: Integer -> Maybe Integer
    raizCubicaEntera2 x
      | null zs   = Nothing
      | otherwise = Just (head zs)
      where factores x = [z | z <- [1..x], mod x z == 0]
            zs         = [y | y <- factores x, y^3 == x]
  2. frahidzam
    import Data.Numbers.Primes (primeFactors)
    import Data.List (nub, group, genericLength)
     
    raizCubicaEntera :: Integer -> Maybe Integer
    raizCubicaEntera n | c n == False = Nothing
                       | otherwise = Just (e n)
     
    a :: Integer -> [(Integer, Integer)]
    a n = zip (map genericLength (group (primeFactors n))) (nub (primeFactors n))
     
    b :: [(Integer, Integer)] -> Bool
    b xs = and [mod a 3 == 0 | (a,b) <- xs]
     
    c :: Integer -> Bool
    c n = b (a n)
     
    d :: Integer -> [(Integer, Integer)]
    d n = zip [div a 3 | (a,b) <- a n] (nub (primeFactors n))
     
    e ::  Integer -> Integer
    e n = product [b^a | (a,b) <- d n]
  3. javmarcha1
     
    raizCubicaEntera :: Integer -> Maybe Integer
    raizCubicaEntera x 
                       | f x == False = Nothing
                       | abc x  == False = Nothing
                       | otherwise = Just (product (d x))
     
     
    c :: Eq a => a -> [a] -> Integer
    c _ [] = 0
    c x (y:ys) | x == y = 1 + c x ys
               | otherwise = c x ys
     
     
     
    nc :: Integer -> [Integer]
    nc n = [ c x (primeFactors n) | x <- (nub (primeFactors n))]
     
    abc :: Integer -> Bool
    abc n = and [ multiplo3 x == True | x <- nc n]
     
    multiplo3 :: Integer -> Bool
    multiplo3 n | rem n 3 == 0 = True
                | otherwise = False
     
    d :: Integer -> [Integer]
    d n  = [ a^(div b 3) | (a,b) <- zip (nub (primeFactors n)) (nc n)]
     
    contar :: Integer -> Integer
    contar n | n < 10 = 1
                      | otherwise = 1 + contar (n `div` 10)
     
    e :: Integer -> Bool
    e x | multiplo3 (contar x -1) == True = True 
        | otherwise = False
     
    f :: Integer -> Bool
    f x | e x == True && x < ((10^(div (contar x -1) 3)+1)^3) && x /= (10^(contar x -1)) = False
        | otherwise = True

Escribe tu solución

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