Menu Close

Siguiente equidigital

Dos números son equidigitales si tienen el mismo multiconjunto de dígitos. Por ejemplo, 2021 y 2120 son equidigitales ya que ambos tiene a {0,1,2,2} como su multiconjunto de dígitos.

Definir la función

   siguienteEquidigital :: Integer -> Maybe Integer

tal que (siguienteEquidigital n) es precisamente el menor número equidigital con n que es mayor que n (es decir, (Just x) si x es dicho número o Nothing si no hay ningún número equidigital con n que sea mayor que n). Por ejemplo,

   siguienteEquidigital 12    ==  Just 21
   siguienteEquidigital 21    ==  Nothing
   siguienteEquidigital 513   ==  Just 531
   siguienteEquidigital 531   ==  Nothing
   siguienteEquidigital 2021  ==  Just 2102
   siguienteEquidigital 2102  ==  Just 2120
   siguienteEquidigital 2120  ==  Just 2201
   siguienteEquidigital 2201  ==  Just 2210
   siguienteEquidigital 2210  ==  Nothing
   fmap (`mod` 1000) (siguienteEquidigital (2^(10^5)))  ==  Just 637

Soluciones

import Data.List (sort)
import Data.Maybe (listToMaybe)
 
-- 1ª solución
-- ===========
 
siguienteEquidigital :: Integer -> Maybe Integer
siguienteEquidigital n
  | null xs = Nothing
  | otherwise = Just (head xs)
  where xs = equidigitalesMayores n
 
-- (equidigitalesMayores n) es la lista de los equidigitales mayores que
-- n. Por ejemplo,
--    equidigitalesMayores 2021  ==  [2102,2120,2201,2210]
--    equidigitalesMayores 2210  ==  []
equidigitalesMayores :: Integer -> [Integer]
equidigitalesMayores n =
  [x | x <- [n+1..mayorEquidigital n],
       sort (show x) == ds]
  where ds = sort (show n)
 
-- (mayorEquidigital n) es el mayor número equidigital con n. Por ejemplo,
--    mayorEquidigital 2021  ==  2210
--    mayorEquidigital 2210  ==  2210
mayorEquidigital :: Integer -> Integer
mayorEquidigital = read . reverse . sort . show
 
-- 2ª solución
-- ===========
 
siguienteEquidigital2 :: Integer -> Maybe Integer
siguienteEquidigital2 = listToMaybe . equidigitalesMayores

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>

6 soluciones de “Siguiente equidigital

  1. Mercedes Vega Gallo
    import Data.List
     
    siguienteEquidigital :: Integer -> Maybe Integer
    siguienteEquidigital n = aux (show n) as
                             where aux a xs|a == last xs = Nothing
                                           |a == head xs = Just $ read $ head $ tail xs
                                           |otherwise = aux a (tail xs)
     
                                   as = nub $ sort $ permutations $ show n
  2. Joaquín Infante Rodríguez
    import Data.List
     
    --La función digitosOrdenados calcula los dígitos de n y los ordena
    --mediante la función sort en una lista.
    --Por ejemplo : digitosOrdenados 2412 == [1,2,2,4] (0.01 secs, 80,776 bytes)
     
    digitosOrdenados :: Integer -> [Integer]
    digitosOrdenados n = sort [read [x] | x<-show n]
     
    --La función listaNumero transforma una lista xs en el correspondiente
    --número que representan esos dígitos.
    --Por ejemplo : listaNumero [2,3,4,5] == 2345 (0.04 secs, 65,376 bytes)
     
    listaNumero :: [Integer] -> Integer
    listaNumero xs = sum [x*10^y | (x,y)<- zip xs [y | y<-reverse [0..genericLength xs-1]]]
     
    --Finalmente, siguienteEquidigital devuelve con Just el siguiente (head) número
    --equidigital (x) desde n hasta el mayor número con igual número de cifras
    --que n ([(n+1)..listaNumero $replicate (genericLength p) 9]) tal que
    --tengan la misma lista de dígitos ordenados (digitosOrdenados n == digitosOrdenados n).
    --Si este no existe, devuelve Nothing.
    --Por ejemplo: siguienteEquidigital 12 == Just 21 (0.11 secs, 147,384 bytes)
    --             siguienteEquidigital 2210  ==  Nothing ((0.26 secs, 125,855,744 bytes)
    --             fmap (`mod` 1000) (siguienteEquidigital (2^(10^5))) == Just 637 (16.33 secs, 30,853,091,608 bytes) 
     
    siguienteEquidigital :: Integer -> Maybe Integer             
    siguienteEquidigital n | xs /= []  = Just (head xs)
                           | otherwise = Nothing
                             where xs = [x | x<- [(n+1)..listaNumero $replicate (genericLength p) 9],
                                             p == digitosOrdenados x]
                                       where p = digitosOrdenados n
  3. Alejandro García Alcaide
    import Data.List (sort, permutations)
     
    siguienteEquidigital :: Integer -> Maybe Integer
    siguienteEquidigital n | not (algunEquidigital n) = Nothing
                           | otherwise                =
                             Just (head [x | x <- [n+1..], esEquidigital x n])
     
    -- Definimos la funcion esEquidigital que verifica si un conjunto de numeros
    -- son equidigitales. Por ejemplo:
    -- esEquidigital 12 21 == True
     
    esEquidigital :: Integer -> Integer -> Bool
    esEquidigital n y = sort (digitos n) == sort (digitos y)
     
    -- La funcion digitos n nos da en una lista los digitos del numero n. Por
    -- ejemplo:
    -- digitos 325 == [3,2,5]
     
    digitos :: Integer -> [Integer]
    digitos n = [read[x]::Integer | x <- show n]
     
    -- Por su parte, la funcion combinaciones nos da las distintas permutaciones de
    -- la lista de los digitos de x. Por otro lado, leeDigito xs toma una lista y
    -- devuelve el numero que representa. 
    combinaciones :: Integer -> [[Integer]]
    combinaciones x = permutations (digitos x)
     
    leeDigito []     = 0
    leeDigito (x:xs) = x * 10 ^ p + leeDigito xs
     where p = length (x:xs) - 1
     
    -- Por ultimo, definimos algunEquidigital que verifica si existe un numero
    -- mayor que x tal que este y x sean equidigitales.
    -- algunEquidigital 50 == False
    -- algunEquidigital 25 == True
    algunEquidigital :: Integer -> Bool
    algunEquidigital x = any (>x) (map leeDigito (combinaciones x))
  4. Rubén Muñoz Mkrtchian
    import Data.List ((\))
     
    siguienteEquidigital :: Integer -> Maybe Integer
    siguienteEquidigital n
      | decreciente xs = Nothing
      | otherwise      = Just (read (aux xs))
          where xs = show n
     
    -- La función decreciente xs se verifica si la lista xs es decreciente, es
    -- decir, si todo elemento es menor o igual que el anterior. Por ejemplo,
    --   λ> decreciente "2021"
    --   False
     
    decreciente :: String -> Bool
    decreciente [_] = True
    decreciente (x:y:zs) = x >= y && decreciente (y:zs)
     
    -- Dada una cadena xs que simboliza un número entero, la función aux xs
    -- devuelve otra cadena que simboliza el entero equidigital siguiente. Por
    -- ejemplo,
    --   λ> aux "2021"
    --   "2102"
     
    aux :: String -> String
    aux (x:xs)
      | decreciente xs = reestructura x (x:xs)
      | otherwise      = x : aux xs
     
    -- Cuando una lista xs (que simboliza un número entero) es decreciente, no
    -- podemos construir un número equidigital que sea posterior a dicho número,
    -- luego la función aux (x:xs) añade el término x a la lista solución hasta
    -- llegar a una lista xs decreciente. En dicho caso, la función reestructura
    -- se encarga de alterar el orden de la lista para construir el número
    -- buscado. Por ejemplo,
    --   λ> reestructura '0' "021"
    --   "102"
     
    reestructura :: Char -> String -> String
    reestructura n (x:xs)
      | elem m xs = m : sort ((x:xs) \ [m])
      | otherwise = reestructura m (x:xs)
          where m = head (show (read [n] + 1))
     
    -- Con esta definición sí se puede calcular el último ejemplo.
    --   λ> fmap (`mod` 1000) (siguienteEquidigital (2^(10^5)))
    --   Just 637
    --   (0.09 secs, 27,530,552 bytes)
  5. Juan María Jiménez Jiménez
     
     
    siguienteEquidigital :: Integer -> Maybe Integer
    siguienteEquidigital n | (filter (>n)
                             (combinacionesDigitos dn)) == [] = Nothing
                           | otherwise = menorCombinacionMayorAN n dn
                             where dn = (digitosConjunto n)
     
    -- digitosConjunto es una funcion que nos da el conjunto de los digitos que conforman un numero:
    -- λ> digitosConjunto 1224
    --[1,2,2,4]
    --(0.00 secs, 76,768 bytes)
    --λ> nub(digitosConjunto (12^3312))
    --[1,7,2,8,3,9,6,0,4,5]
    --(0.01 secs, 13,787,088 bytes)
     
    digitosConjunto :: Integer -> [Integer]
    digitosConjunto n = [ read [c] | c<-(show n)]
     
    --combinacionesDigitos devuelve la lista de todas los posibles numeros que se forman con un lista de numeros xs:
    --λ> combinacionesDigitos [1,4,2]
    --[142,412,241,421,214,124]
     
    combinacionesDigitos :: [Integer] -> [Integer]
    combinacionesDigitos xs = map read (map concat (map f (permutations xs)))
      where f xs =(map (show) xs)
     
    --Finalmente menorCombinacionMayorAN toma el mayor numero de  la lista anterior siempre que éste sea mayor que el numero dado n.
     
    menorCombinacionMayorAN :: Integer -> [Integer] -> Maybe Integer
    menorCombinacionMayorAN n xs | auxs /= [] = Just (minimum $ auxs)
                                 | otherwise = Nothing
      where auxs =  filter (>n) (combinacionesDigitos xs)
  6. ADOLFO ENRIQUE VÁZQUEZ RUIZ
     
    import Data.List
    import Data.Maybe
     
    digitos :: Integer -> [Integer]
    digitos n = [read [x] | x <- show n ]
    --digitos es una función definida por comprensión que , dado un entero , nos
    --devuelve la lista de sus dígitos
     
    digitosANumero :: [Integer] -> Integer
    digitosANumero xs = (read (concat ( map (show) xs ) )) :: Integer
    --digitosANumero es la función inversa a digitos. Dada una lista de dígitos,
    --nos devuelve el número asociado.
     
    siguienteEquidigital :: Integer -> Maybe Integer
    siguienteEquidigital n |dropWhile (<=n) (map (digitosANumero) (sort (permutations (digitos n)))) == []  = Nothing
                                       |otherwise = Just (head(dropWhile (<=n) (map (digitosANumero) (sort (permutations (digitos n))))))

Leave a Reply

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