import Data.Array
-- 1ª solución
-- ===========
maximoIntercambio :: Int -> Int
maximoIntercambio = maximum . intercambios
-- (intercambios x) es la lista de los números obtenidos intercambiando
-- dos dígitos de x. Por ejemplo,
-- intercambios 1234 == [2134,3214,4231,1324,1432,1243]
intercambios :: Int -> [Int]
intercambios x = [intercambio i j x | i <- [0..n-2], j <- [i+1..n-1]]
where n = length (show x)
-- (intercambio i j x) es el número obtenido intercambiando las cifras
-- que ocupan las posiciones i y j (empezando a contar en cero) del
-- número x. Por ejemplo,
-- intercambio 2 5 123456789 == 126453789
intercambio :: Int -> Int -> Int -> Int
intercambio i j x = read (concat [as,[d],cs,[b],ds])
where xs = show x
(as,b:bs) = splitAt i xs
(cs,d:ds) = splitAt (j-i-1) bs
-- 2ª solución (con vectores)
-- ==========================
maximoIntercambio2 :: Int -> Int
maximoIntercambio2 = read . elems . maximum . intercambios2
-- (intercambios2 x) es la lista de los vectores obtenidos
-- intercambiando dos elementos del vector de dígitos de x. Por ejemplo,
-- ghci> intercambios2 1234
-- [array (0,3) [(0,'2'),(1,'1'),(2,'3'),(3,'4')],
-- array (0,3) [(0,'3'),(1,'2'),(2,'1'),(3,'4')],
-- array (0,3) [(0,'4'),(1,'2'),(2,'3'),(3,'1')],
-- array (0,3) [(0,'1'),(1,'3'),(2,'2'),(3,'4')],
-- array (0,3) [(0,'1'),(1,'4'),(2,'3'),(3,'2')],
-- array (0,3) [(0,'1'),(1,'2'),(2,'4'),(3,'3')]]
intercambios2 :: Int -> [Array Int Char]
intercambios2 x = [intercambioV i j v | i <- [0..n-2], j <- [i+1..n-1]]
where xs = show x
n = length xs
v = listArray (0,n-1) xs
-- (intercambioV i j v) es el vector obtenido intercambiando los
-- elementos de v que ocupan las posiciones i y j. Por ejemplo,
-- ghci> intercambioV 2 4 (listArray (0,4) [3..8])
-- array (0,4) [(0,3),(1,4),(2,7),(3,6),(4,5)]
intercambioV :: Int -> Int -> Array Int a -> Array Int a
intercambioV i j v = v // [(i,v!j),(j,v!i)] |
No es correcta.
Esta creo que si es correcta, solucionando el problema con los ceros intermedios
Una función lineal en el número de dígitos de n: