{"id":6805,"date":"2022-03-22T06:00:25","date_gmt":"2022-03-22T04:00:25","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=6805"},"modified":"2022-04-15T12:01:23","modified_gmt":"2022-04-15T10:01:23","slug":"ampliacion-de-matrices-por-columnas","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/ampliacion-de-matrices-por-columnas\/","title":{"rendered":"Ampliaci\u00f3n de matrices por columnas"},"content":{"rendered":"<p>Las matrices enteras se pueden representar mediante tablas con \u00edndices enteros:<\/p>\n<pre lang=\"text\">\n   type Matriz = Array (Int,Int) Int\n<\/pre>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   ampliaColumnas :: Matriz -> Matriz -> Matriz\n<\/pre>\n<p>tal que (ampliaColumnas p q) es la matriz construida a\u00f1adiendo las columnas de la matriz q a continuaci\u00f3n de las de p (se supone que tienen el mismo n\u00famero de filas). Por ejemplo, si p y q representa las dos primeras matrices, entonces (ampliaColumnas p q) es la tercera<\/p>\n<pre lang=\"text\">\n   |0 1|    |4 5 6|    |0 1 4 5 6|\n   |2 3|    |7 8 9|    |2 3 7 8 9|\n<\/pre>\n<p>En Haskell, se definen las dos primeras matrices se definen por<\/p>\n<pre lang=\"text\">\n   ej1 = listArray ((1,1),(2,2)) [0..3]\n   ej2 = listArray ((1,1),(2,3)) [4..9]\n<\/pre>\n<p>y el c\u00e1lculo de la tercera es<\/p>\n<pre lang=\"text\">\n   \u03bb> ampliaColumnas ej1 ej2\n   array ((1,1),(2,5)) [((1,1),0),((1,2),1),((1,3),4),((1,4),5),((1,5),6),\n                        ((2,1),2),((2,2),3),((2,3),7),((2,4),8),((2,5),9)]\n   \u03bb> elems (ampliaColumnas ej1 ej2)\n   [0,1,4,5,6,2,3,7,8,9]\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.Array (Array, (!), array, bounds, elems, listArray)\nimport Data.Matrix (Matrix, (<|>), fromList, ncols, nrows, toList)\nimport Test.QuickCheck\n\ntype Matriz = Array (Int,Int) Int\n\nej1, ej2 :: Matriz\nej1 = listArray ((1,1),(2,2)) [0..3]\nej2 = listArray ((1,1),(2,3)) [4..9]\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nampliaColumnas1 :: Matriz -> Matriz -> Matriz\nampliaColumnas1 p1 p2 =\n  array ((1,1),(m,n1+n2)) [((i,j), f i j) | i <- [1..m], j <- [1..n1+n2]]\n    where ((_,_),(m,n1)) = bounds p1\n          ((_,_),(_,n2)) = bounds p2\n          f i j | j <= n1   = p1!(i,j)\n                | otherwise = p2!(i,j-n1)\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nampliaColumnas2 :: Matriz -> Matriz -> Matriz\nampliaColumnas2 p1 p2 =\n  matriz (matrix p1 <|> matrix p2)\n\n-- (matrix p) es la matriz p en el formatao de Data.Matrix. Por ejemplo,\n--    \u03bb> ej1\n--    array ((1,1),(2,2)) [((1,1),0),((1,2),1),((2,1),2),((2,2),3)]\n--    \u03bb> matrix ej1\n--    \u250c     \u2510\n--    \u2502 0 1 \u2502\n--    \u2502 2 3 \u2502\n--    \u2514     \u2518\n--    \u03bb> matrix (ampliaColumnas1 ej1 ej2)\n--    \u250c           \u2510\n--    \u2502 0 1 4 5 6 \u2502\n--    \u2502 2 3 7 8 9 \u2502\n--    \u2514           \u2518\nmatrix :: Matriz -> Matrix Int\nmatrix p = fromList m n (elems p)\n  where (_,(m,n)) = bounds p\n\n-- (matriz p) es la matriz p en el formato de Data.Array. Por ejemplo,\n--    \u03bb> matriz (fromList 2 3 [1..])\n--    array ((1,1),(2,3)) [((1,1),1),((1,2),2),((1,3),3),((2,1),4),((2,2),5),((2,3),6)]\nmatriz :: Matrix Int -> Matriz\nmatriz p = listArray ((1,1),(nrows p,ncols p)) (toList p)\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\ndata ParMatrices = P Matriz Matriz\n  deriving Show\n\n-- parMatricesArbitrario es un generador de pares de matrices con el\n-- mismo n\u00famero de filas.\nparMatricesArbitrario :: Gen ParMatrices\nparMatricesArbitrario = do\n  m  <- arbitrary `suchThat` (> 0)\n  n1 <- arbitrary `suchThat` (> 0)\n  n2 <- arbitrary `suchThat` (> 0)\n  xs <- vector (m * n1)\n  ys <- vector (m * n2)\n  return (P (listArray ((1,1),(m,n1)) xs)\n            (listArray ((1,1),(m,n2)) ys))\n\n-- ParMatrices es una subclase de Arbitrary\ninstance Arbitrary ParMatrices where\n  arbitrary = parMatricesArbitrario\n\n-- La propiedad es\nprop_ampliaColumna :: ParMatrices -> Bool\nprop_ampliaColumna (P p q) =\n  ampliaColumnas1 p q == ampliaColumnas2 p q\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_ampliaColumna\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> let p = listArray ((1,1),(10^3,10^3)) [1..] in maximum (ampliaColumnas1 p p)\n--    1000000\n--    (2.04 secs, 1,562,652,704 bytes)\n--    \u03bb> let p = listArray ((1,1),(10^3,10^3)) [1..] in maximum (ampliaColumnas2 p p)\n--    1000000\n--    (0.69 secs, 738,508,624 bytes)\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Amplia_columnas.hs\">GitHub<\/a>.<\/p>\n<p>La elaboraci\u00f3n de las soluciones se describe en el siguiente v\u00eddeo<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/Jrz5kxuhD9Y\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h4>Nuevas soluciones<\/h4>\n<ul>\n<li>En los comentarios se pueden escribir nuevas soluciones.\n<li>El c\u00f3digo se debe escribir entre una l\u00ednea con &#60;pre lang=&quot;haskell&quot;&#62; y otra con &#60;\/pre&#62;\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Las matrices enteras se pueden representar mediante tablas con \u00edndices enteros: type Matriz = Array (Int,Int) Int Definir la funci\u00f3n ampliaColumnas :: Matriz -> Matriz -> Matriz tal que (ampliaColumnas p q) es la matriz construida a\u00f1adiendo las columnas de la matriz q a continuaci\u00f3n de las de p (se supone que tienen el mismo&#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":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_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":[2],"tags":[8,507,511,42,146],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6805"}],"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=6805"}],"version-history":[{"count":3,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6805\/revisions"}],"predecessor-version":[{"id":6852,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6805\/revisions\/6852"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=6805"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=6805"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=6805"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}