{"id":1291,"date":"2015-04-07T06:00:57","date_gmt":"2015-04-07T04:00:57","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=1291"},"modified":"2015-05-01T08:43:33","modified_gmt":"2015-05-01T06:43:33","slug":"perimetro-mas-frecuente-de-triangulos-rectangulos","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/perimetro-mas-frecuente-de-triangulos-rectangulos\/","title":{"rendered":"Per\u00edmetro m\u00e1s frecuente de tri\u00e1ngulos rect\u00e1ngulos"},"content":{"rendered":"<p>El grado perimetral de un n\u00famero p es la cantidad de tres tri\u00e1ngulos rect\u00e1ngulos de lados enteros cuyo per\u00edmetro es p. Por ejemplo, el grado perimetral de 120 es 3 ya que s\u00f3lo hay 3 tri\u00e1ngulos rect\u00e1ngulos de lados enteros cuyo per\u00edmetro es 120: {20,48,52}, {24,45,51} y {30,40,50}.<\/p>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   maxGradoPerimetral :: Int -> (Int,[Int])\n<\/pre>\n<p>tal que (maxGradoPerimetral n) es el par (m,ps) tal que m es el m\u00e1ximo grado perimetral de los n\u00fameros menores o iguales que n y ps son los per\u00edmetros, menores o iguales que n, cuyo grado perimetral es m. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   maxGradoPerimetral   50  ==  (1,[12,24,30,36,40,48])\n   maxGradoPerimetral  100  ==  (2,[60,84,90])\n   maxGradoPerimetral  200  ==  (3,[120,168,180])\n   maxGradoPerimetral  400  ==  (4,[240,360])\n   maxGradoPerimetral  500  ==  (5,[420])\n   maxGradoPerimetral  750  ==  (6,[720])\n   maxGradoPerimetral  839  ==  (6,[720])\n   maxGradoPerimetral  840  ==  (8,[840])\n   maxGradoPerimetral 1500  ==  (8,[840,1260])\n   maxGradoPerimetral 2000  ==  (10,[1680])\n   maxGradoPerimetral 3000  ==  (12,[2520])\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.List\nimport Data.Array (accumArray, assocs)\n\n-- 1\u00aa soluci\u00f3n                                                      --\n-- ===========\n\nmaxGradoPerimetral1 :: Int -> (Int,[Int])\nmaxGradoPerimetral1 p = (m,[x | (n,x) <- ts, n == m])\n    where ts    = [(length (triangulos x),x) | x <- [1..p]] \n          (m,_) = maximum ts \n\n-- (triangulos p) es el conjunto de tri\u00e1ngulos rect\u00e1ngulos de per\u00edmetro\n-- p. Por ejemplo,\n--    triangulos 120  ==  [(20,48,52),(24,45,51),(30,40,50)]\ntriangulos :: Int -> [(Int,Int,Int)]\ntriangulos p = \n    [(a,b,c) | a <- [1..q],\n               b <- [a..q],\n               let c = p-a-b,\n               a*a+b*b == c*c]\n    where q = p `div` 2\n\n-- 2\u00aa soluci\u00f3n                                                      --\n-- ===========\n\nmaxGradoPerimetral2 :: Int -> (Int,[Int])\nmaxGradoPerimetral2 p = (m,[x | (n,x) <- ts, n == m])\n    where ts    = [(n,x) | (x,n) <- numeroPerimetrosTriangulos p, n > 0]\n          (m,_) = maximum ts \n\n-- (numeroPerimetrosTriangulos p) es la lista formado por los n\u00fameros de\n-- 1 a p y la cantidad de tri\u00e1ngulos rect\u00e1ngulos enteros cuyo per\u00edmetro\n-- es dicho n\u00famero. Por ejemplo,\n--    ghci>  [(p,n) | (p,n) <- numeroPerimetrosTriangulos 70, n > 0]\n--    [(12,1),(24,1),(30,1),(36,1),(40,1),(48,1),(56,1),(60,2),(70,1)]\nnumeroPerimetrosTriangulos :: Int -> [(Int,Int)] \nnumeroPerimetrosTriangulos p = \n    assocs (accumArray (\\x _ -> 1+x) 0 (1,p) (perimetrosTriangulos p))\n\n-- (perimetrosTriangulos p) es la lista formada por los per\u00edmetros y los\n-- lados de los tri\u00e1ngulos rect\u00e1ngulos enteros cuyo per\u00edmetro es menor o\n-- igual que p. Por ejemplo,\n--    ghci> perimetrosTriangulos 70\n--    [(12,(3,4,5)),   (30,(5,12,13)),(24,(6,8,10)),  (56,(7,24,25)),\n--     (40,(8,15,17)), (36,(9,12,15)),(60,(10,24,26)),(48,(12,16,20)),\n--     (60,(15,20,25)),(70,(20,21,29))]\nperimetrosTriangulos :: Int -> [(Int,(Int,Int,Int))]\nperimetrosTriangulos p =\n    [(q,(a,b,c)) | a <- [1..p1],\n                   b <- [a..p1],\n                   esCuadrado (a*a+b*b), \n                   let c = raizCuadradaE (a*a+b*b), \n                   let q = a+b+c,\n                   q <= p]\n    where p1 = p `div` 2\n\n-- (esCuadrado n) se verifica si n es un cuadrado. Por ejemplo,\n--    esCuadrado 25  ==  True\n--    esCuadrado 27  ==  False\nesCuadrado :: Int -> Bool\nesCuadrado n = a*a == n\n    where a = raizCuadradaE n\n\n-- (raizCuadradaE n) es la ra\u00edz cuadrada entera de n. Por ejemplo,\n--    raizCuadradaE 25  ==  5\n--    raizCuadradaE 27  ==  5\n--    raizCuadradaE 35  ==  5\n--    raizCuadradaE 36  ==  6\nraizCuadradaE :: Int -> Int\nraizCuadradaE = floor . sqrt . fromIntegral\n\n-- 3\u00aa soluci\u00f3n                                                      --\n-- ===========\n\nmaxGradoPerimetral3 :: Int -> (Int,[Int])\nmaxGradoPerimetral3 p = (m,[x | (n,x) <- ts, n == m])\n    where ts    = [(n,x) | (x,n) <- numeroPerimetrosTriangulos2 p, n > 0]\n          (m,_) = maximum ts \n\n-- (numeroPerimetrosTriangulos2 p) es la lista formado por los n\u00fameros de\n-- 1 a p y la cantidad de tri\u00e1ngulos rect\u00e1ngulos enteros cuyo per\u00edmetro\n-- es dicho n\u00famero. Por ejemplo,\n--    ghci>  [(p,n) | (p,n) <- numeroPerimetrosTriangulos2 70, n > 0]\n--    [(12,1),(24,1),(30,1),(36,1),(40,1),(48,1),(56,1),(60,2),(70,1)]\nnumeroPerimetrosTriangulos2 :: Int -> [(Int,Int)] \nnumeroPerimetrosTriangulos2 p = \n    [(head xs, length xs) | xs <- group (sort (perimetrosTriangulos2 p))]\n\n-- (perimetrosTriangulos2 p) es la lista formada por los per\u00edmetros de\n-- los tri\u00e1ngulos rect\u00e1ngulos enteros cuyo per\u00edmetro es menor o igual\n-- que p. Por ejemplo, \n--    perimetrosTriangulos2 70  ==  [12,30,24,56,40,36,60,48,60,70]\nperimetrosTriangulos2 :: Int -> [Int]\nperimetrosTriangulos2 p =\n    [q | a <- [1..p1],\n         b <- [a..p1],\n         esCuadrado (a*a+b*b), \n         let c = raizCuadradaE (a*a+b*b), \n         let q = a+b+c,\n         q <= p]\n    where p1 = p `div` 2\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    ghci> maxGradoPerimetral1 1000\n--    (8,[840])\n--    (120.08 secs, 21116625136 bytes)\n--    ghci> maxGradoPerimetral2 1000\n--    (8,[840])\n--    (0.66 secs, 132959056 bytes)\n--    ghci> maxGradoPerimetral3 1000\n--    (1000,[1])\n--    (0.66 secs, 133443816 bytes)\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>El grado perimetral de un n\u00famero p es la cantidad de tres tri\u00e1ngulos rect\u00e1ngulos de lados enteros cuyo per\u00edmetro es p. Por ejemplo, el grado perimetral de 120 es 3 ya que s\u00f3lo hay 3 tri\u00e1ngulos rect\u00e1ngulos de lados enteros cuyo per\u00edmetro es 120: {20,48,52}, {24,45,51} y {30,40,50}. Definir la funci\u00f3n maxGradoPerimetral :: Int ->&#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":[7],"tags":[249,55,8,30,282,183,13,28,42,15,14,236],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/1291"}],"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=1291"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/1291\/revisions"}],"predecessor-version":[{"id":1326,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/1291\/revisions\/1326"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=1291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=1291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=1291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}