Ir al contenido principal

Cuadrados ondulantes

Un número se dice ondulante si sus cifras alternan entre dos valores. Por ejemplo, 272 es ondulante, así como 2727. El primer cuadrado ondulante no trivial (todos los cuadrados de dos cifras son ondulantes) es 121 = 11^2.

Definir la función

cuadradosOndulantes :: Integer -> [Integer]

tal que (cuadradosOndulantes n) es la lista de los cuadrados ondulantes menores que n^2. Por ejemplo,

λ> cuadradosOndulantes 50000
[0,1,4,9,16,25,36,49,64,81,121,484,676,69696]

Soluciones

import Data.List (isPrefixOf)

cuadradosOndulantes :: Integer -> [Integer]
cuadradosOndulantes n =
  [x^2 | x <- [0..n]
       , ondulante (x^2)]

-- 1ª definición de ondulante
ondulante1 :: Integer -> Bool
ondulante1 n
  | n < 100   = True
  | otherwise = aux zs x y
  where (x:y:zs)       = show n
        aux [] _ _     = True
        aux (c:cs) a b = c == a && aux cs b a

-- 2ª definición de ondulante
ondulante2 :: Integer -> Bool
ondulante2 n = (drop 2 xs) `isPrefixOf` xs
  where xs = show n

-- Comparación de eficiencia
--    λ> length [n | n <- [1..10^6], ondulante1 n]
--    459
--    (5.73 secs, 1,115,105,408 bytes)
--    λ> length [n | n <- [1..10^6], ondulante2 n]
--    459
--    (2.01 secs, 467,856,432 bytes)

-- Se usará como ondulante la 2ª
ondulante :: Integer -> Bool
ondulante = ondulante2

Referencias