Menu Close

Factorial generalizado

El factorial generalizado de x respecto de y y z es el producto x(x-z)(x-2z) … (x-(y-1)z). Por ejemplo, el factorial generalizado de 7 respecto de 3 y 2 es 7x5x3 = 105 y el de 7 respecto de 2 y 3 es 7×4 = 28

Definir la función

   factGen :: Integer -> Integer -> Integer -> Integer

tal que (factGen x y z) es el factorial generalizado de x respecto de y y z. Por ejemplo,

   factGen 7 3 2  ==  105
   factGen 7 2 3  ==  28

Nota: Se supone que x, y y z son positivos y z < x.

Comprobar con QuickCheck que (factGen x x 1) es el factorial de x.

Soluciones

import Test.QuickCheck
 
-- 1ª definición (por comprensión):
factGen :: Integer -> Integer -> Integer -> Integer
factGen x y z = product [x,x-z..x-(y-1)*z]
 
-- 2ª definición (por recursión):
factGen2 :: Integer -> Integer -> Integer -> Integer
factGen2 x 1 _ = x
factGen2 x y z = x * factGen2 (x-z) (y-1) z
 
-- Propiedad de equivalencia
prop_equiv :: Positive Integer
           -> Positive Integer -> Positive Integer -> Property
prop_equiv (Positive x) (Positive y) (Positive z) =
    z < x ==> factGen x y z == factGen2 x y z
 
-- La comprobación es
--    λ> quickCheck prop_equiv
--    +++ OK, passed 100 tests.
 
-- La propiedad es       
prop_factGen :: Positive Integer -> Bool
prop_factGen (Positive x) =
    factGen x x 1 == product [1..x]
 
-- La comprobación es      
--    λ> quickCheck prop_factGen
--    +++ OK, passed 100 tests.

Solución en Maxima

factGen (x,y,z) := genfact (x,y,z)$

8 soluciones de “Factorial generalizado

  1. fracruzam
    import Test.QuickCheck
     
    factGen :: Integer -> Integer -> Integer -> Integer
    factGen x y z = product [x,x-z..x-(y-1)*z]
     
    fact :: Integer -> Integer
    fact 0 = 1
    fact x = product [1..x] 
     
    prop :: (Positive Integer) -> Bool
    prop (Positive x) = fact x == factGen x x 1
     
    -- λ> quickCheck prop
    -- +++ OK, passed 100 tests.
    • fracruzam

      En realidad, la ecuación fact 0 = 1 es innecesaria. Podría simplificarse.

  2. juamorrom1
    import Test.QuickCheck
     
    factGen :: Integer -> Integer -> Integer -> Integer
    factGen x y z = product [ x-(m*z) | m <- [0..y-1] ]
     
    prop_factGen :: Positive Integer -> Bool
    prop_factGen (Positive x) = factGen x x 1 == fact x
     
    fact :: (Enum a, Num a) => a -> a
    fact x = product [1..x]
     
    -- *Main> quickCheck prop_factGen
    -- +++ OK, passed 100 tests.
  3. manvermor
    import Test.QuickCheck
     
    factGen :: Integer -> Integer -> Integer -> Integer
    factGen x y z = product $ take (fromIntegral y) (iterate (+(-z)) x)
     
    prop_factGen :: Positive Integer -> Bool
    prop_factGen (Positive x) = factGen x x 1 == product [1..x]
     
    -- *Main> quickCheck prop_factGen
    -- +++ OK, passed 100 tests.
  4. abrdelrod
    import Test.QuickCheck
     
    factGen :: Integer -> Integer -> Integer -> Integer
    factGen x y z = product $ map (k -> x-k*z) [0..y-1]
     
    prop_factGen :: Positive Integer -> Bool
    prop_factGen (Positive x) = factGen x x 1 == product [1..x]
     
    -- *Main> quickCheck prop_factGen
    -- +++ OK, passed 100 tests.
  5. Chema Cortés
    import Test.QuickCheck
     
    factGen :: Integer -> Integer -> Integer -> Integer
    factGen x y z = product [x, x-z..(x-(y-1)*z)]
     
    prop_factGen :: Positive Integer -> Bool
    prop_factGen (Positive x) = factGen x x 1 == product [1..x]
  6. erisan
    factGen (x,y,z) := block (lreduce("*",create_list(x-(m*z),m,makelist(k,k,0,y-1))))$
  7. Alejandro

    En Maxima está predefinido

    factGen (x,y,z) := genfact (x,y,z)$

Escribe tu solución

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