Menu Close

Producto de los elementos de la diagonal principal

Las matrices se pueden representar como lista de listas de la misma longitud, donde cada uno de sus elementos representa una fila de la matriz.

Definir la función

   productoDiagonalPrincipal :: Num a => [[a]] -> a

tal que (productoDiagonalPrincipal xss) es el producto de los elementos de la diagonal principal de la matriz cuadrada xss. Por ejemplo,

   productoDiagonal1 [[3,5,2],[4,7,1],[6,9,8]]  ==  168
   productoDiagonal1 (replicate 5 [1..5])       ==  120
   length (show (productoDiagonal3 (replicate 30000 [1..30000])))  ==  121288

Soluciones

import Data.List (genericReplicate)
 
-- 1ª solución
-- ===========
 
productoDiagonal1 :: Num a => [[a]] -> a
productoDiagonal1 xss = product (diagonal1 xss)
 
-- (diagonal1 xss) es la diagonal de la matriz xss. Por ejemplo,
--    diagonal1 [[3,5,2],[4,7,1],[6,9,0]]  ==  [3,7,0]
--    diagonal1 [[3,5],[4,7],[6,9]]        ==  [3,7]
--    diagonal1 [[3,5,2],[4,7,1]]          ==  [3,7]
diagonal1 :: [[a]] -> [a]
diagonal1 ((x:_):xss) = x : diagonal1 (map tail xss)
diagonal1 _           = []
 
-- 2ª solución
-- ===========
 
productoDiagonal2 :: Num a => [[a]] -> a
productoDiagonal2 = product . diagonal1
 
-- 3ª solución
-- ===========
 
productoDiagonal3 :: Num a => [[a]] -> a
productoDiagonal3 = product . diagonal3
 
diagonal3 :: [[a]] -> [a]
diagonal3 xss = [xs !! k | (xs,k) <- zip xss [0..n]]
  where n = length (head xss) - 1
 
-- 4ª solución
-- ===========
 
productoDiagonal4 :: Num a => [[a]] -> a
productoDiagonal4 []          = 1
productoDiagonal4 [[]]        = 1
productoDiagonal4 ((x:_):xss) = x * productoDiagonal4 (map tail xss)
 
-- 5ª solución
-- ===========
 
productoDiagonal5 :: Num a => [[a]] -> a
productoDiagonal5 xss = product (zipWith (!!) xss [0..k])
  where m = length xss
        n = length (head xss)
        k = min m n - 1
 
-- Comparación de eficiencia
-- =========================
 
ejemplo :: Integer -> [[Integer]]
ejemplo n = genericReplicate n [1..n]
 
-- La comparación es
--    λ> length (show (productoDiagonal1 (ejemplo 7000)))
--    23878
--    (1.23 secs, 3,396,129,424 bytes)
--    λ> length (show (productoDiagonal2 (ejemplo 7000)))
--    23878
--    (0.94 secs, 3,396,127,680 bytes)
--    λ> length (show (productoDiagonal3 (ejemplo 7000)))
--    23878
--    (0.09 secs, 44,841,864 bytes)
--    λ> length (show (productoDiagonal4 (ejemplo 7000)))
--    23878
--    (0.96 secs, 3,614,137,840 bytes)
--    λ> length (show (productoDiagonal5 (ejemplo 7000)))
--    23878
--    (0.07 secs, 44,168,984 bytes)
--
--    λ> length (show (productoDiagonal3 (ejemplo 70000)))
--    308760
--    (8.26 secs, 5,359,752,408 bytes)
--    λ> length (show (productoDiagonal5 (ejemplo 70000)))
--    308760
--    (9.34 secs, 5,353,035,656 bytes)

El código se encuentra en GitHub.

Ejercicio

3 soluciones de “Producto de los elementos de la diagonal principal

  1. j0sejuan
    import Relude.Unsafe (at)
     
    productoDiagonalPrincipal = product . zipWith at [0..]
  2. Alejandro Bueno
    productoDiagonal :: Num a => [[a]] -> a
    productoDiagonal xss = product (diagonal xss)
     
    diagonal :: [[a]] -> [a]
    diagonal ((x:_):xss) = x : diagonal (map tail xss)
    diagonal _           = []
  3. Blanca Castro
    productoDiagonal :: Num a => [[a]] -> a
    productoDiagonal xss = product (zipWith (!!) xss [0..])

Escribe tu solución

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