Menu Close

Último dígito no nulo del factorial

El factorial de 7 es

   7! = 1 * 2 * 3 * 4 * 5 * 6 * 7 = 5040

por tanto, el último dígito no nulo del factorial de 7 es 4.

Definir la función

   ultimoNoNuloFactorial :: Integer -> Integer

tal que (ultimoNoNuloFactorial n) es el último dígito no nulo del factorial de n. Por ejemplo,

   ultimoNoNuloFactorial  7  == 4
   ultimoNoNuloFactorial 10  == 8
   ultimoNoNuloFactorial 12  == 6
   ultimoNoNuloFactorial 97  == 2
   ultimoNoNuloFactorial  0  == 1

Comprobar con QuickCheck que si n es mayor que 4, entonces el último dígito no nulo del factorial de n es par.

Soluciones

import Data.Char (digitToInt)
import Test.QuickCheck
 
-- 1ª solución
-- ===========
 
ultimoNoNuloFactorial :: Integer -> Integer
ultimoNoNuloFactorial = ultimoNoNulo . factorial
 
-- (factorial n) es el factorial de n. Por ejemplo,
--    factorial 7  ==  5040
factorial :: Integer -> Integer
factorial n = product [1..n]
 
-- (ultimoNoNulo n) es el último dígito no nulo de n. Por ejemplo,
--    ultimoNoNulo 5040  ==  4
ultimoNoNulo :: Integer -> Integer
ultimoNoNulo n | r /= 0    = r
               | otherwise = ultimoNoNulo q
  where (q,r) = n `quotRem` 10
 
-- 2ª solución
-- ===========
 
ultimoNoNuloFactorial2 :: Integer -> Integer
ultimoNoNuloFactorial2 = last . filter (/= 0) . digitos . factorial
 
digitos :: Integer -> [Integer]
digitos n = [read [x] | x <- show n]
 
-- 3ª solución
-- ===========
 
ultimoNoNuloFactorial3 :: Integer -> Integer
ultimoNoNuloFactorial3 = last . filter (/= 0) . digitos3 . factorial3
 
digitos3 :: Integer -> [Integer]
digitos3 = map (fromIntegral . digitToInt) . show
 
factorial3 :: Integer -> Integer
factorial3 = product . enumFromTo 1
 
-- 4ª solución
-- ===========
 
ultimoNoNulo4 :: Integer -> Integer
ultimoNoNulo4 n = read [head (dropWhile (=='0') (reverse (show n)))]
 
-- 5ª solución
-- ===========
 
ultimoNoNulo5 :: Integer -> Integer
ultimoNoNulo5 =
  read . return . head . dropWhile ('0' ==) . reverse . show
 
-- Propiedad
-- =========
 
-- La propiedad es
prop_ultimoNoNuloFactorial :: Integer -> Property
prop_ultimoNoNuloFactorial n = 
  n > 4 ==> even (ultimoNoNuloFactorial n)
 
-- La comprobación es
--    ghci> quickCheck prop_ultimoNoNuloFactorial
--    +++ OK, passed 100 tests.

Pensamiento

Busca el tu esencial,
que no está en ninguna parte
y en todas partes está.

Antonio Machado

5 soluciones de “Último dígito no nulo del factorial

  1. rebgongor
    ultimoNoNuloFactorial :: Integer -> Integer
    ultimoNoNuloFactorial n = noNulos (factorial n)
     
    noNulos :: Integer -> Integer
    noNulos n | r /= 0    = r
              | otherwise = noNulos (div n 10)
      where r = rem n 10
     
    factorial :: Integer -> Integer
    factorial n = product [1..n]
     
    prop_ultimoNoNuloFactorial :: Integer -> Property
    prop_ultimoNoNuloFactorial n =
      n > 4 ==> even (ultimoNoNuloFactorial n)
     
    -- Comprobación:
    --    λ> quickCheck prop_ultimoNoNuloFactorial
    --    +++ OK, passed 100 tests
  2. juabaerui
    ultimoNoNuloFactorial :: Integer -> Integer
    ultimoNoNuloFactorial n = last [x | x <- digitos n, x /= 0]
     
    digitos :: Integer -> [Integer]
    digitos n = [read [x] | x <- show (product [1..n])]
     
    prop_ultimoNoNuloFactorial :: Integer -> Property
    prop_ultimoNoNuloFactorial n = n > 4 ==> even (ultimoNoNuloFactorial n)
     
    {- λ> quickCheck prop_ultimoNoNuloFactorial
    +++ OK, passed 100 tests. -}
  3. Carlos
    -- ---------------------------------------------------------------------
    -- Importación de librerías auxiliares                                            --
    -- ---------------------------------------------------------------------
     
    import Test.Hspec
    import Test.QuickCheck
     
    -- (factorial n) calcula el factorial de un numero entero.
    -- Por ejemplo,
    -- λ> factorial 12
    -- 479001600
    -- (0.00 secs, 120,328 bytes)
     
    factorial :: Integer -> Integer
    factorial n = foldl (*) 1 [1..n]
     
    -- (digitos n) proporciona la lista formada por los digitos de un numero.
    -- Por ejemplo,
    -- λ> digitos 596787
    -- [5,9,6,7,8,7]
    -- (0.00 secs, 141,888 bytes)
     
    digitos :: Integer -> [Integer]
    digitos n = [read [x] | x <- show n]
     
    -- (quitaElemento xs n) elimina todos los números n que formen parte de una lista.
    -- Por ejemplo,
    -- λ> quitaElemento [2,4,8,2,3,4,4,0,5,7,1] 4
    -- [2,8,2,3,0,5,7,1]
    -- (0.00 secs, 122,728 bytes)
     
    quitaElemento :: (Eq a) => [a] -> a -> [a]
    quitaElemento xs n = [ x | x <- xs , x /= n]
     
    ultimoNoNuloFactorial :: Integer -> Integer
    ultimoNoNuloFactorial n = last(quitaElemento (digitos(factorial n)) 0)
     
    prop_ultimoNoNuloFactorial :: Integer -> Property
    prop_ultimoNoNuloFactorial n =
      n > 4 ==> even (ultimoNoNuloFactorial n)
     
    -- λ> quickCheck prop_ultimoNoNuloFactorial 
    -- +++ OK, passed 100 tests; 346 discarded.
    -- (0.03 secs, 17,556,912 bytes)
     
    -- ---------------------------------------------------------------------
    --  § Verificacion                                                                            --
    -- ---------------------------------------------------------------------
     
     
    verifica :: IO ()
    verifica = hspec $ do
      describe "ultimoNoNuloFactorial" $ do
        it "e1" $ do 
          ultimoNoNuloFactorial 7 `shouldBe` 4
        it "e2" $ do
          ultimoNoNuloFactorial 10 `shouldBe` 8
        it "e3" $ do
          ultimoNoNuloFactorial 12 `shouldBe` 6
        it "e4" $ do
          ultimoNoNuloFactorial 97 `shouldBe` 2
        it "e5" $ do
          ultimoNoNuloFactorial 0 `shouldBe` 1
     
     
    -- λ> verifica
     
    -- ultimoNoNuloFactorial
      -- e1
      -- e2
      -- e3
      -- e4
      -- e5
     
    -- Finished in 0.0008 seconds
    -- 5 examples, 0 failures
    -- (0.00 secs, 405,656 bytes)
  4. antgongar
    import Test.QuickCheck
     
    ultimoNoNuloFactorial :: Integer -> Integer
    ultimoNoNuloFactorial = last . filter (/= 0) . digitos . factorial
     
    digitos :: Integer -> [Integer]
    digitos n = [read [x] | x <- show n]
     
    factorial :: Integer -> Integer
    factorial n = product [1..n]
     
    prop_ultimoNoNuloFactorial :: Integer -> Property
    prop_ultimoNoNuloFactorial n =
      n > 4 ==> even (ultimoNoNuloFactorial n)
     
    -- La comprobación es
    --    λ> quickCheck prop_ultimoNoNuloFactorial
    --    OK, passed 100 tests.
    • antgongar

      Las funciones digitos y factorial también se pueden definir sin argumentos, como sigue:

      import Test.QuickCheck
      import Data.Char (digitToInt)
       
      ultimoNoNuloFactorial :: Integer -> Integer
      ultimoNoNuloFactorial = last . filter (/= 0) . digitos . factorial
       
      digitos :: Integer -> [Integer]
      digitos = map (fromIntegral . digitToInt) . show
       
      factorial :: Integer -> Integer
      factorial = product . enumFromTo 1
       
      prop_ultimoNoNuloFactorial :: Integer -> Property
      prop_ultimoNoNuloFactorial n =
        n > 4 ==> even (ultimoNoNuloFactorial n)
       
      -- La comprobación es
      --    λ> quickCheck prop_ultimoNoNuloFactorial
      --    OK, passed 100 tests.

Escribe tu solución

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