-- 1ª definición
-- =============
nRotacionesDivisiblesPor8 :: Integer -> Int
nRotacionesDivisiblesPor8 x =
length [y | y <- rotaciones x
, y `mod` 8 == 0]
-- rotaciones 1234 == [1234,2341,3412,4123]
rotaciones :: Integer -> [Integer]
rotaciones x = [read ys | ys <- rotacionesLista xs]
where xs = show x
-- rotacionesLista "abcd" == ["abcd","bcda","cdab","dabc"]
rotacionesLista :: [a] -> [[a]]
rotacionesLista xs =
[zs ++ ys | k <- [0 .. length xs - 1]
, let (ys,zs) = splitAt k xs]
-- 2ª definición
-- =============
nRotacionesDivisiblesPor8b :: Integer -> Int
nRotacionesDivisiblesPor8b x =
length [y | y <- tresDigitosConsecutivos x
, y `mod` 8 == 0]
-- tresDigitosConsecutivos 1234 == [123,234,341,412]
tresDigitosConsecutivos :: Integer -> [Integer]
tresDigitosConsecutivos x =
[read (take 3 ys) | ys <- rotacionesLista (show x)]
-- Comparación de eficiencia
-- =========================
-- λ> nRotacionesDivisiblesPor8 (read (take (3*10^3) (cycle "248")))
-- 2000
-- (3.59 secs, 4,449,162,144 bytes)
-- λ> nRotacionesDivisiblesPor8b (read (take (3*10^3) (cycle "248")))
-- 2000
-- (0.48 secs, 593,670,656 bytes)