{"id":5806,"date":"2020-04-21T05:30:48","date_gmt":"2020-04-21T03:30:48","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=5806"},"modified":"2020-04-29T07:22:52","modified_gmt":"2020-04-29T05:22:52","slug":"combinaciones-divisibles","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/combinaciones-divisibles\/","title":{"rendered":"Combinaciones divisibles"},"content":{"rendered":"<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\"> \n   tieneCombinacionDivisible :: [Int] -> Int -> Bool\n<\/pre>\n<p>tal que (tieneCombinacionDivisible xs m) se verifica si existe alguna forma de combinar todos los elementos de la lista (con las operaciones suma o resta) de forma que el resultado sea divisible por m. Por ejemplo,<\/p>\n<pre lang=\"text\"> \n   tieneCombinacionDivisible [1,3,4,6] 4  ==  True\n   tieneCombinacionDivisible [1,3,9]   2  ==  False\n<\/pre>\n<p>En el primer ejemplo, 1 &#8211; 2 + 3 + 4 + 6 = 12 es una combinaci\u00f3n divisible por 4. En el segundo ejemplo, las combinaciones de [1,3,9] son<\/p>\n<pre lang=\"text\"> \n   1 + 3 + 9 =  13\n  -1 + 3 + 9 =  11\n   1 - 3 + 9 =   7\n  -1 - 3 + 9 =   5\n   1 + 3 - 9 =  -5\n  -1 + 3 - 9 =  -7\n   1 - 3 - 9 = -11\n  -1 - 3 - 9 = -13\n<\/pre>\n<p>y ninguna de las 4 es divisible por 2.<\/p>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Test.QuickCheck\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\ntieneCombinacionDivisible :: [Int] -> Int -> Bool\ntieneCombinacionDivisible xs m =\n  any esDivisible (valoresCombinaciones xs)\n  where esDivisible x = x `mod` m == 0\n\n-- (valoresCombinaciones xs) es la lista de los valores de todas las\n-- combinaciones de todos los elementos de la lista con las operaciones\n-- suma o resta. Por ejemplo,\n--    \u03bb> valoresCombinaciones [1,3,4,6]\n--    [14,12,8,6,6,4,0,-2,2,0,-4,-6,-6,-8,-12,-14]\n--    \u03bb> valoresCombinaciones [1,3,-4,6]\n--    [6,4,0,-2,14,12,8,6,-6,-8,-12,-14,2,0,-4,-6]\nvaloresCombinaciones :: [Int] -> [Int]\nvaloresCombinaciones []     = []\nvaloresCombinaciones [x]    = [x,-x]\nvaloresCombinaciones (x:xs) = concat [[y + x, y - x] | y <- ys]\n  where ys = valoresCombinaciones xs\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\ntieneCombinacionDivisible2 :: [Int] -> Int -> Bool\ntieneCombinacionDivisible2 xs m =\n  tieneCombinacionCongruente xs m 0\n\n-- (tieneCombinacionCongruente xs m a) se verifica si existe alguna\n-- forma de combinar todos los elementos de la lista xs (con las\n-- operaciones suma o resta) de forma que el resultado sea congruente\n-- con a m\u00f3dulo m. Por ejemplo,\n--    tieneCombinacionCongruente [1,3,4,6] 4 0  ==  True\n--    tieneCombinacionCongruente [1,3,4,6] 4 1  ==  False\n--    tieneCombinacionCongruente [1,3,9] 2 0    ==  False\n--    tieneCombinacionCongruente [1,3,9] 2 1    ==  True\ntieneCombinacionCongruente :: [Int] -> Int -> Int -> Bool\ntieneCombinacionCongruente []  _  _ = False\ntieneCombinacionCongruente [x] m  a = (x - a) `mod` m == 0\ntieneCombinacionCongruente (x:xs) m a =\n  tieneCombinacionCongruente xs m (a-x) ||\n  tieneCombinacionCongruente xs m (a+x)\n\n-- Equivalencia\n-- ============\n\n-- La propiedad es\nprop_tieneCombinacionDivisible :: [Int] -> Positive Int -> Bool\nprop_tieneCombinacionDivisible xs (Positive m) =\n  tieneCombinacionDivisible xs m == tieneCombinacionDivisible2 xs m\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheckWith (stdArgs {maxSize=25}) prop_tieneCombinacionDivisible\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n--    \u03bb> (n,xs,m) = (200,[-n..n],sum [1..n]) \n--    (0.00 secs, 0 bytes)\n--    \u03bb> and [tieneCombinacionDivisible xs a | a <- [1..m]]\n--    True\n--    (4.74 secs, 6,536,494,976 bytes)\n--    \u03bb> and [tieneCombinacionDivisible2 xs a | a <- [1..m]]\n--    True\n--    (2.97 secs, 3,381,932,664 bytes)\n<\/pre>\n<h4>Otras soluciones<\/h4>\n<ul>\n<li>Se pueden escribir otras soluciones 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","protected":false},"excerpt":{"rendered":"<p>Definir la funci\u00f3n tieneCombinacionDivisible :: [Int] -> Int -> Bool tal que (tieneCombinacionDivisible xs m) se verifica si existe alguna forma de combinar todos los elementos de la lista (con las operaciones suma o resta) de forma que el resultado sea divisible por m. Por ejemplo, tieneCombinacionDivisible [1,3,4,6] 4 == True tieneCombinacionDivisible [1,3,9] 2 ==&#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":[4],"tags":[163,8,12,89,11,6],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/5806"}],"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=5806"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/5806\/revisions"}],"predecessor-version":[{"id":5829,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/5806\/revisions\/5829"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=5806"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=5806"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=5806"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}