{"id":8512,"date":"2024-03-09T06:00:45","date_gmt":"2024-03-09T04:00:45","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=8512"},"modified":"2024-03-08T20:28:30","modified_gmt":"2024-03-08T18:28:30","slug":"09-mar-24","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/09-mar-24\/","title":{"rendered":"Producto de los elementos de la diagonal principal"},"content":{"rendered":"<p>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.<\/p>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"haskell\">\n   productoDiagonalPrincipal :: Num a => [[a]] -> a\n<\/pre>\n<p>tal que (productoDiagonalPrincipal xss) es el producto de los elementos de la diagonal principal de la matriz cuadrada xss. Por ejemplo,<\/p>\n<pre lang=\"haskell\">\n   productoDiagonal [[3,5,2],[4,7,1],[6,9,8]]  ==  168\n   productoDiagonal (replicate 5 [1..5])       ==  120\n   length (show (productoDiagonal (replicate 30000 [1..30000])))  ==  121288\n<\/pre>\n<p><!--more--><\/p>\n<p><a name=\"haskell\"><\/a><\/p>\n<h2>1. Soluciones en Haskell<\/h2>\n<pre lang=\"haskell\">\nmodule Producto_de_los_elementos_de_la_diagonal_principal where\n\nimport Data.List (genericReplicate)\nimport Test.Hspec (Spec, describe, hspec, it, shouldBe)\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nproductoDiagonal1 :: Num a => [[a]] -> a\nproductoDiagonal1 xss = product (diagonal1 xss)\n\n-- (diagonal1 xss) es la diagonal de la matriz xss. Por ejemplo,\n--    diagonal1 [[3,5,2],[4,7,1],[6,9,0]]  ==  [3,7,0]\n--    diagonal1 [[3,5],[4,7],[6,9]]        ==  [3,7]\n--    diagonal1 [[3,5,2],[4,7,1]]          ==  [3,7]\ndiagonal1 :: [[a]] -> [a]\ndiagonal1 ((x:_):xss) = x : diagonal1 (map tail xss)\ndiagonal1 _           = []\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nproductoDiagonal2 :: Num a => [[a]] -> a\nproductoDiagonal2 = product . diagonal1\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\nproductoDiagonal3 :: Num a => [[a]] -> a\nproductoDiagonal3 = product . diagonal3\n\ndiagonal3 :: [[a]] -> [a]\ndiagonal3 xss = [xs !! k | (xs,k) <- zip xss [0..n]]\n  where n = length (head xss) - 1\n\n-- 4\u00aa soluci\u00f3n\n-- ===========\n\nproductoDiagonal4 :: Num a => [[a]] -> a\nproductoDiagonal4 []          = 1\nproductoDiagonal4 [[]]        = 1\nproductoDiagonal4 ((x:_):xss) = x * productoDiagonal4 (map tail xss)\n\n-- 5\u00aa soluci\u00f3n\n-- ===========\n\nproductoDiagonal5 :: Num a => [[a]] -> a\nproductoDiagonal5 xss = product (zipWith (!!) xss [0..k])\n  where m = length xss\n        n = length (head xss)\n        k = min m n - 1\n\n-- Verificaci\u00f3n\n-- ============\n\nverifica :: IO ()\nverifica = hspec spec\n\nspecG :: ([[Integer]] -> Integer) -> Spec\nspecG productoDiagonal = do\n  it \"e1\" $\n    productoDiagonal [[3,5,2],[4,7,1],[6,9,8]]  `shouldBe`  168\n  it \"e2\" $\n    productoDiagonal (replicate 5 [1..5])       `shouldBe`  120\n\nspec :: Spec\nspec = do\n  describe \"def. 1\" $ specG productoDiagonal1\n  describe \"def. 2\" $ specG productoDiagonal2\n  describe \"def. 3\" $ specG productoDiagonal3\n  describe \"def. 4\" $ specG productoDiagonal4\n  describe \"def. 5\" $ specG productoDiagonal5\n\n-- La verificaci\u00f3n es\n--    \u03bb> verifica\n--\n--    10 examples, 0 failures\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\nejemplo :: Integer -> [[Integer]]\nejemplo n = genericReplicate n [1..n]\n\n-- La comparaci\u00f3n es\n--    \u03bb> length (show (productoDiagonal1 (ejemplo 7000)))\n--    23878\n--    (1.23 secs, 3,396,129,424 bytes)\n--    \u03bb> length (show (productoDiagonal2 (ejemplo 7000)))\n--    23878\n--    (0.94 secs, 3,396,127,680 bytes)\n--    \u03bb> length (show (productoDiagonal3 (ejemplo 7000)))\n--    23878\n--    (0.09 secs, 44,841,864 bytes)\n--    \u03bb> length (show (productoDiagonal4 (ejemplo 7000)))\n--    23878\n--    (0.96 secs, 3,614,137,840 bytes)\n--    \u03bb> length (show (productoDiagonal5 (ejemplo 7000)))\n--    23878\n--    (0.07 secs, 44,168,984 bytes)\n--\n--    \u03bb> length (show (productoDiagonal3 (ejemplo 70000)))\n--    308760\n--    (8.26 secs, 5,359,752,408 bytes)\n--    \u03bb> length (show (productoDiagonal5 (ejemplo 70000)))\n--    308760\n--    (9.34 secs, 5,353,035,656 bytes)\n<\/pre>\n<p><a name=\"python\"><\/a><\/p>\n<h2>2. Soluciones en Python<\/h2>\n<pre lang=\"python\">\nfrom functools import reduce\nfrom operator import mul\nfrom sys import set_int_max_str_digits, setrecursionlimit\nfrom timeit import Timer, default_timer\n\nset_int_max_str_digits(10**6)\nsetrecursionlimit(10**6)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\n# diagonal1(xss) es la diagonal de la matriz xss. Por ejemplo,\n#    diagonal1([[3,5,2],[4,7,1],[6,9,0]])  ==  [3,7,0]\n#    diagonal1([[3,5],[4,7],[6,9]])        ==  [3,7]\n#    diagonal1([[3,5,2],[4,7,1]])          ==  [3,7]\ndef diagonal1(xss: list[list[int]]) -> list[int]:\n    if not xss:\n        return []\n    if not xss[0]:\n        return []\n    return [xss[0][0]] + diagonal1(list(map((lambda ys : ys[1:]), xss[1:])))\n\ndef producto(xs: list[int]) -> int:\n    return reduce(mul, xs)\n\ndef productoDiagonal1(xss: list[list[int]]) -> int:\n    return producto(diagonal1(xss))\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef diagonal2(xss: list[list[int]]) -> list[int]:\n    n = min(len(xss), len(xss[0]))\n    return [xss[k][k] for k in range(n)]\n\ndef productoDiagonal2(xss: list[list[int]]) -> int:\n    return producto(diagonal2(xss))\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef productoDiagonal3(xss: list[list[int]]) -> int:\n    if not xss:\n        return 1\n    if not xss[0]:\n        return 1\n    return xss[0][0] * productoDiagonal3(list(map((lambda ys : ys[1:]), xss[1:])))\n\n# Verificaci\u00f3n\n# ============\n\ndef test_productoDiagonal() -> None:\n    for productoDiagonal in [productoDiagonal1, productoDiagonal2,\n                             productoDiagonal3]:\n        assert productoDiagonal([[3,5,2],[4,7,1],[6,9,8]]) == 168\n        assert productoDiagonal([[1, 2, 3, 4, 5]]*5) == 120\n    print(\"Verificado\")\n\n# La verificaci\u00f3n es\n#    >>> test_productoDiagonal()\n#    Verificado\n\n# Comparaci\u00f3n de eficiencia\n# =========================\n\n# ejemplo(n) es la matriz con n filas formadas por los n\u00fameros de 1 a\n# n. Por ejemplo,\n#    >>> ejemplo(3)\n#    [[1, 2, 3], [1, 2, 3], [1, 2, 3]]\ndef ejemplo(n: int) -> list[list[int]]:\n    return [list(range(1, n+1))]*n\n\ndef tiempo(e: str) -> None:\n    \"\"\"Tiempo (en segundos) de evaluar la expresi\u00f3n e.\"\"\"\n    t = Timer(e, \"\", default_timer, globals()).timeit(1)\n    print(f\"{t:0.2f} segundos\")\n\n# La comparaci\u00f3n es\n#    >>> tiempo('productoDiagonal1(ejemplo(1200))')\n#    1.97 segundos\n#    >>> tiempo('productoDiagonal2(ejemplo(1200))')\n#    0.00 segundos\n#    >>> tiempo('productoDiagonal3(ejemplo(1200))')\n#    1.56 segundos\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>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\u00f3n productoDiagonalPrincipal :: Num a => [[a]] -> a tal que (productoDiagonalPrincipal xss) es el producto de los elementos de la diagonal principal de la matriz cuadrada xss&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"default","_kad_post_title":"default","_kad_post_layout":"default","_kad_post_sidebar_id":"","_kad_post_content_style":"default","_kad_post_vertical_padding":"default","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[581],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8512"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=8512"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8512\/revisions"}],"predecessor-version":[{"id":8513,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/8512\/revisions\/8513"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=8512"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=8512"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=8512"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}