{"id":6925,"date":"2022-04-14T07:00:35","date_gmt":"2022-04-14T05:00:35","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=6925"},"modified":"2022-04-13T18:06:00","modified_gmt":"2022-04-13T16:06:00","slug":"numero-de-inversiones","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/numero-de-inversiones\/","title":{"rendered":"N\u00famero de inversiones"},"content":{"rendered":"<p>Se dice que en una sucesi\u00f3n de n\u00fameros x(1), x(2), &#8230;, x(n) hay una inversi\u00f3n cuando existe un par de n\u00fameros x(i) > x(j), siendo i &lt; j. Por ejemplo, en la permutaci\u00f3n 2, 1, 4, 3 hay dos inversiones (2 antes que 1 y 4 antes que 3) y en la permutaci\u00f3n 4, 3, 1, 2 hay cinco inversiones (4 antes 3, 4 antes 1, 4 antes 2, 3 antes 1, 3 antes 2).<\/p>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   numeroInversiones :: Ord a => [a] -> Int\n<\/pre>\n<p>tal que <code>(numeroInversiones xs)<\/code> es el n\u00famero de inversiones de <code>xs<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   numeroInversiones [2,1,4,3]  ==  2\n   numeroInversiones [4,3,1,2]  ==  5\n<\/pre>\n<h4>Soluciones<\/h4>\n<p>[schedule expon=&#8217;2022-04-21&#8242; expat=\u00bb06:00&#8243;]<\/p>\n<ul>\n<li>Las soluciones se pueden escribir en los comentarios.\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<p>[\/schedule]<\/p>\n<p>[schedule on=&#8217;2022-04-21&#8242; at=\u00bb06:00&#8243;]<\/p>\n<pre lang=\"haskell\">\r\nimport Test.QuickCheck (quickCheck)\r\nimport Data.Array ((!), listArray)\r\n\r\n-- 1\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nnumeroInversiones1 :: Ord a => [a] -> Int\r\nnumeroInversiones1 = length . indicesInversiones\r\n\r\n-- (indicesInversiones xs) es la lista de los \u00edndices de las inversiones\r\n-- de xs. Por ejemplo,\r\n--    indicesInversiones [2,1,4,3]  ==  [(0,1),(2,3)]\r\n--    indicesInversiones [4,3,1,2]  ==  [(0,1),(0,2),(0,3),(1,2),(1,3)]\r\nindicesInversiones :: Ord a => [a] -> [(Int,Int)]\r\nindicesInversiones xs = [(i,j) | i <- [0..n-2],\r\n                                 j <- [i+1..n-1],\r\n                                 xs!!i > xs!!j]\r\n  where n = length xs\r\n\r\n-- 2\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nnumeroInversiones2 :: Ord a => [a] -> Int\r\nnumeroInversiones2 = length . indicesInversiones2\r\n\r\nindicesInversiones2 :: Ord a => [a] -> [(Int,Int)]\r\nindicesInversiones2 xs = [(i,j) | i <- [0..n-2],\r\n                                  j <- [i+1..n-1],\r\n                                  v!i > v!j]\r\n  where n = length xs\r\n        v = listArray (0,n-1) xs\r\n\r\n-- 3\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nnumeroInversiones3 :: Ord a => [a] -> Int\r\nnumeroInversiones3 = length . inversiones\r\n\r\n-- (inversiones xs) es la lista de las inversiones  de xs. Por ejemplo,\r\n--    Inversiones [2,1,4,3]  ==  [(2,1),(4,3)]\r\n--    Inversiones [4,3,1,2]  ==  [(4,3),(4,1),(4,2),(3,1),(3,2)]\r\ninversiones :: Ord a => [a] -> [(a,a)]\r\ninversiones []     = []\r\ninversiones (x:xs) = [(x,y) | y <- xs, y < x] ++ inversiones xs\r\n\r\n-- 4\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nnumeroInversiones4 :: Ord a => [a] -> Int\r\nnumeroInversiones4 []     = 0\r\nnumeroInversiones4 (x:xs) = length (filter (x>) xs) + numeroInversiones4 xs\r\n\r\n-- Comprobaci\u00f3n de equivalencia\r\n-- ============================\r\n\r\n-- La propiedad es\r\nprop_numeroInversiones :: [Int] -> Bool\r\nprop_numeroInversiones xs =\r\n  all (== numeroInversiones1 xs)\r\n      [numeroInversiones2 xs,\r\n       numeroInversiones3 xs,\r\n       numeroInversiones4 xs]\r\n\r\n-- La comprobaci\u00f3n es\r\n--    \u03bb> quickCheck prop_numeroInversiones\r\n--    +++ OK, passed 100 tests.\r\n\r\n-- Comparaci\u00f3n de eficiencia\r\n-- =========================\r\n\r\n-- La comparaci\u00f3n es\r\n--    \u03bb> numeroInversiones1 [1200,1199..1]\r\n--    719400\r\n--    (2.30 secs, 236,976,776 bytes)\r\n--    \u03bb> numeroInversiones2 [1200,1199..1]\r\n--    719400\r\n--    (0.61 secs, 294,538,488 bytes)\r\n--    \u03bb> numeroInversiones3 [1200,1199..1]\r\n--    719400\r\n--    (0.26 secs, 150,543,056 bytes)\r\n--    \u03bb> numeroInversiones4 [1200,1199..1]\r\n--    719400\r\n--    (0.10 secs, 41,274,888 bytes)\r\n--\r\n--    \u03bb> numeroInversiones3 [3000,2999..1]\r\n--    4498500\r\n--    (1.35 secs, 937,186,992 bytes)\r\n--    \u03bb> numeroInversiones4 [3000,2999..1]\r\n--    4498500\r\n--    (0.61 secs, 253,665,928 bytes)\r\n<\/pre>\n<p>El c\u00f3digo se encuentra en [GitHub](https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/<\/p>\n<p>La elaboraci\u00f3n de las soluciones se describe en el siguiente v\u00eddeo<\/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<p>[\/schedule]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Se dice que en una sucesi\u00f3n de n\u00fameros x(1), x(2), &#8230;, x(n) hay una inversi\u00f3n cuando existe un par de n\u00fameros x(i) > x(j), siendo i &lt; j. Por ejemplo, en la permutaci\u00f3n 2, 1, 4, 3 hay dos inversiones (2 antes que 1 y 4 antes que 3) y en la permutaci\u00f3n 4, 3,&#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":[41,8,507,38,28,72,11,6,542,146],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6925"}],"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=6925"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6925\/revisions"}],"predecessor-version":[{"id":6926,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6925\/revisions\/6926"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=6925"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=6925"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=6925"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}