Máximo de las rotaciones restringidas
Rotar un número a la iquierda significa pasar su primer dígito al final. Por ejemplo, rotando a la izquierda el 56789 se obtiene 67895.
Las rotaciones restringidas del número 56789 se obtienen como se indica a continución:
- Se inicia con el propio número: 56789
- El anterior se rota a la izquierda y se obtiene el 67895.
- Del anterior se fija el primer dígito y se rota a la iquierda los otros. Se obtiene 68957.
- Del anterior se fijan los 2 primeros dígito y se rota a la iquierda los otros. Se obtiene 68579.
- Del anterior se fijan los 3 primeros dígito y se rota a la iquierda los otros. Se obtiene 68597.
El proceso ha terminado ya que conservando los cuatro primeros queda sólo un dígito que al girar es él mismo. Por tanto, la sucesión de las rotaciones restringidas de 56789 es
1 |
56789 -> 67895 -> 68957 -> 68579 -> 68597 |
y su mayor elemento es 68957.
Definir la función
1 |
maxRotaciones :: Integer -> Integer |
tal que (maxRotaciones n) es el máximo de las rotaciones restringidas del número n. Por ejemplo,
1 2 3 4 |
maxRotaciones 56789 == 68957 maxRotaciones 1347902468 == 3790246814 maxRotaciones 6 == 6 maxRotaciones 2017 == 2017 |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
-- 1ª solución -- =========== maxRotaciones :: Integer -> Integer maxRotaciones = read . aux . show where aux n@[_] = n aux n@(x1:x2:xs) = max n (x2:aux (xs ++ [x1])) -- 2ª solución -- =========== maxRotaciones2 :: Integer -> Integer maxRotaciones2 n | n < 10 = n | otherwise = maximum [ read (us ++ vs) | (us,vs) <- take m (iterate siguiente ("",xs)) ] where xs = show n m = length xs -- siguiente ("","56789") == ("6","7895") -- siguiente ("6","7895") == ("68","957") -- siguiente ("68","957") == ("685","79") -- siguiente ("685","79") == ("6859","7") -- siguiente ("6859","7") == ("6859","7") siguiente :: (String,String) -> (String,String) siguiente (xs,a:b:ys) = (xs ++ [b], ys ++ [a]) siguiente (xs,[a]) = (xs,[a]) -- 3ª solución -- =========== maxRotaciones3 :: Integer -> Integer maxRotaciones3 = read . aux . show where aux (x:y:xs) | x > y = x : y : xs | otherwise = y : (aux $ xs ++ [x]) aux [x] = [x] aux _ = [] -- Comparación de eficiencia -- ========================= -- λ> length (show (maxRotaciones (n (5*10^3)))) -- 5001 -- (2.74 secs, 802,282,616 bytes) -- λ> length (show (maxRotaciones2 (n (5*10^3)))) -- 5001 -- (18.23 secs, 12,375,579,216 bytes) -- λ> length (show (maxRotaciones3 (n (5*10^3)))) -- 5001 -- (0.67 secs, 729,155,056 bytes) |
Es probable que se pueda simplificar, así como mejorar el rendimiento pero aquí va una primera definición.
Aquí un intento
Se calcula directamente el máximo, sin iterar entre todas las rotaciones posibles.
Coste cuadrático:
Respecto coste lineal: