Menu Close

Sumas de potencias que son cuadrados perfectos

El 2º problema de la ONEM (Olimpíada Nacional Escolar de Matemática) de Mayo del 2020 dice

Determinar si existen enteros positivos a, b y c, no necesariamente distintos, tales que a+b+c=2020 y 2^a + 2^b + 2^c es un cuadrado perfecto.

Definir la función

   soluciones :: Integer -> Integer -> [(Integer,Integer,Integer)]

tales que (soluciones k n) es la lista de las ternas no decrecientes (a,b,c) tales que que a+b+c=n y k^a + k^b + k^c es un cuadrado perfecto. Por ejemplo,

   soluciones 2 19  ==  [(2,6,11),(2,7,10),(4,7,8),(5,5,9),(6,6,7)]
   soluciones 3 19  ==  []
   take 2 (soluciones 2 2020)  ==  [(2,674,1344),(4,674,1342)]

Soluciones

soluciones :: Integer -> Integer -> [(Integer,Integer,Integer)]
soluciones k n =
  [(a,b,c) | a <- [1..n `div` 3],
             b <- [a..n-a],
             let c = n-a-b,
             c >= b,
             esCuadradoPerfecto (k^a + k^b + k^c)]
 
-- (esCuadradoPerfecto x) se verifica si x es un cuadrado perfecto. Por
-- ejemplo,
--    esCuadradoPerfecto 16  ==  True
--    esCuadradoPerfecto 27  ==  False
esCuadradoPerfecto :: Integer -> Bool
esCuadradoPerfecto x =
  (raizEntera x)^2 == x
 
-- (raizEntera x) es el mayor entero cuyo cuadrado es menor o igual que
-- x. Por ejemplo,
--    raizEntera 16  ==  4
--    raizEntera 27  ==  5
raizEntera :: Integer -> Integer
raizEntera x = aux (1,x)
    where aux (a,b) | d == x    = c
                    | c == a    = c
                    | d < x     = aux (c,b)
                    | otherwise = aux (a,c)
              where c = (a+b) `div` 2
                    d = c^2

Nuevas soluciones

  • En los comentarios se pueden escribir nuevas soluciones.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>
Medio

4 soluciones de “Sumas de potencias que son cuadrados perfectos

  1. Rubén Muñoz Mkrtchian
    soluciones :: Integer -> Integer -> [(Integer,Integer,Integer)]
    soluciones k n = [(a,b,c) | a <- [1..m],
                                b <- [a..2*m],
                                let c = n - a - b,
                                b <= c,
                                esPerfecto (k^a + k^b + k^c)]
                                  where m = div n 3
     
    -- esPerfecto n se verifica si n es un cuadrado perfecto. Por ejemplo,
    --   λ> esPerfecto 40
    --   False
    --   λ> esPerfecto 64
    --   True
     
    esPerfecto :: Integer -> Bool
    esPerfecto n = (round (sqrt (fromInteger n))) ^ 2 == n
     
    -- Para números grandes que se dan en soluciones 2 2020, la definición de
    -- esPerfecto n no permite calcular todas las soluciones posibles.
    --   λ> sqrt (2^2+2^674+2^1344)
    --   Infinity
    --   λ> esPerfecto (2^2+2^674+2^1344)
    --   False
    • José A. Alonso

      La definición esPerfecto es incorrecta. Por ejemplo,

      λ> 10^64 == (10^32)^2
      True

      pero 10^64 es un cuadrado perfecto (es el cuadrado de 10^32)

      λ> round (sqrt (fromInteger (10^64)))
      99999999999999987351763694911488
      λ> it^2 == 10^64
      False

      El fallo está en el uso de número decimales. Por ejemplo.

      λ> round (sqrt (fromInteger (10^64)))
      99999999999999987351763694911488
      λ> it^2 == 10^64
      False
  2. Joaquín Infante Rodríguez
    import Data.List
     
    cuadradoPerfecto :: Integer -> Bool
    cuadradoPerfecto x = length [n | n<-[1..x], x == n^2] == 1
     
    soluciones :: Integer -> Integer -> [(Integer,Integer,Integer)]
    soluciones k n = [(a,b,c) | c<-[1..n] , b<-[1..c] , a<-[1..b] , a+b+c==n, cuadradoPerfecto(k^a + k^b + k^c)]
  3. Alejandro García Alcaide
    -- Con todas las restricciones del enunciado, la funcion quedaría:
    soluciones :: Integer -> Integer -> [(Integer,Integer,Integer)]
    soluciones k n =
      [(a,b,c) | a <- [1..x], b <- [a..2*x],let c = n-a-b, c >= b, esCuadradoPerfecto (k^a + k^b + k^c)]
     where x = div n 3
     
    -- Definimos la sucesion de los cuadrados perfectos. 
    cuadradosPerfectos :: [Integer]
    cuadradosPerfectos = [x^2 | x <- [1..]]
     
    -- Definimos una funcion que verifique si un numero es cuadrado perfecto o no. 
    esCuadradoPerfecto :: Integer -> Bool
    esCuadradoPerfecto n = last (takeWhile (<=n) cuadradosPerfectos) == n

Leave a Reply

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