Menu Close

Rotaciones divisibles por 4

Las rotaciones de 928160 son 928160, 281609, 816092, 160928, 609281 y 92816. De las cuales, las divisibles por 4 son 928160, 816092, 160928 y 92816.

Definir la función

   nRotacionesDivisibles :: Integer -> Int

tal que (nRotacionesDivisibles n) es el número de rotaciones del número n divisibles por 4. Por ejemplo,

   nRotacionesDivisibles 928160          ==  4
   nRotacionesDivisibles 44              ==  2
   nRotacionesDivisibles (1234^50000)    ==  38684
   nRotacionesDivisibles (1234^300000)   ==  231853

Soluciones

import Data.Char (digitToInt)
 
-- 1ª definición
-- =============
 
nRotacionesDivisibles :: Integer -> Int
nRotacionesDivisibles n =
  length [x | x <- rotacionesNumero n, x `mod` 4 == 0]
 
 
-- (rotacionesNumero) es la lista de la rotaciones del número n. Por
-- ejemplo,
--    rotacionesNumero 235  ==  [235,352,523]
rotacionesNumero :: Integer -> [Integer]
rotacionesNumero = map read . rotaciones . show
 
-- (rotaciones xs) es la lista de las rotaciones obtenidas desplazando
-- el primer elemento xs al final. Por ejemplo,
--    rotaciones [2,3,5]  ==  [[2,3,5],[3,5,2],[5,2,3]]
rotaciones :: [a] -> [[a]]
rotaciones xs = take (length xs) (iterate rota xs)
 
-- (rota xs) es la lista añadiendo el primer elemento de xs al
-- final. Por ejemplo, 
--    rota [3,2,5,7]  ==  [2,5,7,3]
rota :: [a] -> [a]
rota (x:xs) = xs ++ [x]
 
-- 2ª definición
-- =============
 
nRotacionesDivisibles2 :: Integer -> Int
nRotacionesDivisibles2 n = 
  length [x | x <- pares n, x `mod` 4 == 0]
 
-- (pares n) es la lista de pares de elementos consecutivos, incluyendo
-- el último con el primero. Por ejemplo,
--    pares 928160  ==  [9,92,28,81,16,60]
pares :: Integer -> [Int]
pares n =
  read [last ns,head ns] : [read [a,b] | (a,b) <- zip ns (tail ns)]
  where ns = show n
 
-- 3ª definición
-- =============
 
nRotacionesDivisibles3 :: Integer -> Int
nRotacionesDivisibles3 n =
  ( length
  . filter (0 ==)
  . map (`mod` 4)
  . zipWith (\x y -> 2*x + y) d
  . tail
  . (++[i])) d
  where
    d@(i:dn) = (map digitToInt . show) n
 
-- Comparación de eficiencia
-- =========================
 
--    λ> nRotacionesDivisibles (123^1500)
--    803
--    (8.15 secs, 7,109,852,800 bytes)
--    λ> nRotacionesDivisibles2 (123^1500)
--    803
--    (0.05 secs, 0 bytes)
--    λ> nRotacionesDivisibles3 (123^1500)
--    803
--    (0.02 secs, 0 bytes)
--
--    λ> nRotacionesDivisibles2 (1234^50000)
--    38684
--    (2.24 secs, 1,160,467,472 bytes)
--    λ> nRotacionesDivisibles3 (1234^50000)
--    38684
--    (0.31 secs, 68,252,040 bytes)
Medio

15 soluciones de “Rotaciones divisibles por 4

  1. albcercid
     
    ex :: Integer -> Int
    ex n = aux (map read $ f $ t)
      where t = show n
            f [x] = [[x,head t]]
            f (x:y:xs) = [x,y]:f (y:xs)
            aux [] = 0
            aux (x:xs) | mod x 4 == 0 = 1 + aux xs
                       | otherwise = aux xs
    • albcercid
       
      -- Definición anterior:
       
      -- λ> ex (1234^(50000))
      -- 38684
      -- (0.69 secs, 605,821,440 bytes)
       
      -- Nueva definición:
       
      nRotacionesDivisibles :: Integer -> Int
      nRotacionesDivisibles n = aux2 t
            where t = show n
                  aux2 [x] | mod (read [x,head t]) 4 == 0 = 1
                           | otherwise = 0
                  aux2 (x:y:xs) | mod (read [x,y]) 4 == 0 = 1 + aux2 (y:xs)
                                | otherwise = aux2 (y:xs)
       
       
      -- λ> nRotacionesDivisibles (1234^(50000))
      -- 38684
      -- (0.58 secs, 597,351,344 bytes)
       
      -- Al reducir el número de veces que se recorre la lista, el tiempo disminuye.
  2. eliguivil
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles = aux [] . show
      where
        aux xs c@(y:ys) | c `elem` xs           = 0
                        | (read c) `mod` 4 == 0 = 1 + aux (c:xs) (ys++[y])
                        | otherwise             = aux (c:xs) (ys++[y])
  3. Daniel
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles n =
      length [ y | y <- rotaciones n , mod y 4 == 0]
     
    rotaciones :: Integer -> [Integer]
    rotaciones n =
      map read [drop x (show n) ++ take x (show n)
               | x <- [0..length (show n) - 1]]
  4. glovizcas
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles n = length [ x | x <- rotaciones (show n),
                                           mod (read x) 4 == 0]
     
    rotaciones :: Eq a => [a] -> [[a]]
    rotaciones xs = nub [drop n xs ++ take n xs | n <- [0..length xs-1]]
  5. enrnarbej
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles n = (length
                            . filter (0 ==)
                            . map (`mod` 4)
                            . zipWith (x y -> 2*x + y) d
                            . tail
                            . (++[i])) d
                           where
                            digitos  = map digitToInt . show
                            d@(i:dn) = digitos n
  6. Juanjo Ortega (juaorture)

    import Data.List
    import Test.QuickCheck

    — Primera definición (poco eficiente):
    rotaciones :: Integer -> [Integer]
    rotaciones x = map read [drop n xs ++ take n xs | n [Integer]
    rotaciones’ x = map read (tail (zipWith (++) (tails xs) (inits xs)))
    where xs = show x

    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles = length . filter (\x -> x mod 4 == 0) . rotaciones’

    — Sabiendo que un número es divisible por 4 si sus dos últimas cifras lo son, se crean las siguientes funciones:
    digitos :: Integer -> [String]
    digitos a = [[x] | x [Int]
    lista n = map read (zipWith (++) (x:xs) (xs++[x]))
    where (x:xs) = digitos n

    nRotacionesDivisibles’ :: Integer -> Int
    nRotacionesDivisibles’ = length . filter (\x -> x mod 4 == 0) . lista

    — Se comprueba con QuickCheck la equivalencia entre definiciones:
    prop :: Integer -> Property
    prop x = x > 0 ==> nRotacionesDivisibles x == nRotacionesDivisibles’ x

    — La comprobación es:
    — *Main> quickCheck prop
    — +++ OK, passed 100 tests.

    — El cálculo del último ejemplo:
    — *Main> nRotacionesDivisibles’ (1234^50000)
    — 38684
    — (0.35 secs, 709,561,984 bytes)

  7. Juanjo Ortega (juaorture)

    Y ahora en estilo haskell… :D

    import Data.List
    import Test.QuickCheck
     
    – Primera definición (poco eficiente):
    rotaciones :: Integer -> [Integer]
    rotaciones x = map read [drop n xs ++ take n xs | n [Integer]
    rotaciones’ x = map read (tail (zipWith (++) (tails xs) (inits xs)))
    where xs = show x
     
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles = length . filter (x -> x mod 4 == 0) . rotaciones’
     
    – Sabiendo que un número es divisible por 4 si sus dos últimas cifras lo son, se crean las siguientes funciones:
    digitos :: Integer -> [String]
    digitos a = [[x] | x [Int]
    lista n = map read (zipWith (++) (x:xs) (xs++[x]))
    where (x:xs) = digitos n
     
    nRotacionesDivisibles’ :: Integer -> Int
    nRotacionesDivisibles’ = length . filter (x -> x mod 4 == 0) . lista
     
    – Se comprueba con QuickCheck la equivalencia entre definiciones:
    prop :: Integer -> Property
    prop x = x > 0 ==> nRotacionesDivisibles x == nRotacionesDivisibles’ x
     
    – La comprobación es:*Main> quickCheck prop
    – +++ OK, passed 100 tests.
     
    – El cálculo del último ejemplo:*Main> nRotacionesDivisibles’ (1234^50000)38684(0.35 secs, 709,561,984 bytes)
  8. Juanjo Ortega (juaorture)

    A la tercera va la vencida…

    import Data.List
    import Test.QuickCheck
     
    --Primera definición (poco eficiente):
    rotaciones :: Integer -> [Integer]
    rotaciones x = map read [drop n xs ++ take n xs | n [Integer]
    rotaciones’ x = map read (tail (zipWith (++) (tails xs) (inits xs)))
    where xs = show x
     
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles = length . filter (x -> x mod 4 == 0) . rotaciones’
     
    -- Sabiendo que un número es divisible por 4 si sus dos últimas cifras lo son, se crean las siguientes funciones:
    digitos :: Integer -> [String]
    digitos a = [[x] | x [Int]
    lista n = map read (zipWith (++) (x:xs) (xs++[x]))
    where (x:xs) = digitos n
     
    nRotacionesDivisibles’ :: Integer -> Int
    nRotacionesDivisibles’ = length . filter (x -> x mod 4 == 0) . lista
     
    -- Se comprueba con QuickCheck la equivalencia entre definiciones:
    prop :: Integer -> Property
    prop x = x > 0 ==> nRotacionesDivisibles x == nRotacionesDivisibles’ x
     
    -- La comprobación es:
    -- *Main> quickCheck prop
    -- +++ OK, passed 100 tests.
     
    -- El cálculo del último ejemplo:
    -- *Main> nRotacionesDivisibles’ (1234^50000)
    -- 38684
    -- (0.35 secs, 709,561,984 bytes)
  9. margarflo5
     
    import Data.Char
     
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles n =
      length [ x | x <- rotaciones (show n),
              (digitToInt (last x)+ (digitToInt (last (init x)))*10) `mod` 4 == 0 ]
     
    rotaciones :: Eq a => [a] -> [[a]]
    rotaciones xs = [drop n xs ++ take n xs | n <- [0..length xs-1]]
  10. marlobrip
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles n =
      length [ x | x <- rotaciones (show n), (read x) `mod` 4 == 0]
     
    rotaciones :: [a] -> [[a]]
    rotaciones xs = [ drop n xs ++ take n xs | n <- [1..length xs]]
  11. cescarde
    nRotacionesDivisibles :: Integer -> Int
    nRotacionesDivisibles n = entre4 $ funci d d
                    where d = digitos n
     
    digitos :: Integer -> [Integer]
    digitos n = [read [x] | x <- show n]
     
    funci :: Num a => [a] -> [a] -> [a]
    funci (x:y:xs) zs =  10*x+y : funci (y:xs) zs
    funci [x] (y:_) = 10*x+y : []
     
    entre4 :: (Integral a1, Num a) => [a1] -> a
    entre4 [] = 0
    entre4 (x:xs) | mod x 4 == 0 = 1 + entre4 xs
                  | otherwise = 0 + entre4 xs

Escribe tu solución

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