{"id":6894,"date":"2022-04-11T13:40:11","date_gmt":"2022-04-11T11:40:11","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=6894"},"modified":"2022-04-11T13:40:11","modified_gmt":"2022-04-11T11:40:11","slug":"codigo-de-las-alergias","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/codigo-de-las-alergias\/","title":{"rendered":"C\u00f3digo de las alergias"},"content":{"rendered":"<p>Para la determinaci\u00f3n de las alergia se utiliza los siguientes c\u00f3digos para los al\u00e9rgenos:<\/p>\n<pre lang=\"text\">\n   Huevos ........   1\n   Cacahuetes ....   2\n   Mariscos ......   4\n   Fresas ........   8\n   Tomates .......  16\n   Chocolate .....  32\n   Polen .........  64\n   Gatos ......... 128\n<\/pre>\n<p>As\u00ed, si Juan es al\u00e9rgico a los cacahuetes y al chocolate, su puntuaci\u00f3n es 34 (es decir, 2+32).<\/p>\n<p>Los al\u00e9rgenos se representan mediante el siguiente tipo de dato<\/p>\n<pre lang=\"text\">\n  data Alergeno = Huevos\n                | Cacahuetes\n                | Mariscos\n                | Fresas\n                | Tomates\n                | Chocolate\n                | Polen\n                | Gatos\n    deriving (Enum, Eq, Show, Bounded)\n<\/pre>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   alergias :: Int -> [Alergeno]\n<\/pre>\n<p>tal que (alergias n) es la lista de alergias correspondiente a una puntuaci\u00f3n n. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> alergias 1\n   [Huevos]\n   \u03bb> alergias 2\n   [Cacahuetes]\n   \u03bb> alergias 3\n   [Huevos,Cacahuetes]\n   \u03bb> alergias 5\n   [Huevos,Mariscos]\n   \u03bb> alergias 255\n   [Huevos,Cacahuetes,Mariscos,Fresas,Tomates,Chocolate,Polen,Gatos]\n<\/pre>\n<h4>Soluciones<\/h4>\n<p>[schedule expon=&#8217;2022-04-18&#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-18&#8242; at=\u00bb06:00&#8243;]<\/p>\n<pre lang=\"haskell\">\r\nimport Data.List (subsequences)\r\nimport Test.QuickCheck\r\n\r\ndata Alergeno =\r\n    Huevos\r\n  | Cacahuetes\r\n  | Mariscos\r\n  | Fresas\r\n  | Tomates\r\n  | Chocolate\r\n  | Polen\r\n  | Gatos\r\n  deriving (Enum, Eq, Show, Bounded)\r\n\r\n-- 1\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nalergias1 :: Int -> [Alergeno]\r\nalergias1 n =\r\n  [a | (a,c) <- zip alergenos codigos, c `elem` descomposicion n]\r\n\r\n-- codigos es la lista de los c\u00f3digos de los alergenos.\r\ncodigos :: [Int]\r\ncodigos = [2^x| x <- [0..7]]\r\n\r\n-- (descomposicion n) es la descomposici\u00f3n de n como sumas de potencias\r\n-- de 2. Por ejemplo,\r\n--    descomposicion 3    ==  [1,2]\r\n--    descomposicion 5    ==  [1,4]\r\n--    descomposicion 248  ==  [8,16,32,64,128]\r\n--    descomposicion 255  ==  [1,2,4,8,16,32,64,128]\r\ndescomposicion :: Int -> [Int]\r\ndescomposicion n =\r\n  head [xs | xs <- subsequences codigos, sum xs == n]\r\n\r\n-- 2\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nalergias2 :: Int -> [Alergeno]\r\nalergias2 = map toEnum . codigosAlergias\r\n\r\n-- (codigosAlergias n) es la lista de c\u00f3digos de alergias\r\n-- correspondiente a una puntuaci\u00f3n n. Por ejemplo,\r\n--    codigosAlergias 1  ==  [0]\r\n--    codigosAlergias 2  ==  [1]\r\n--    codigosAlergias 3  ==  [0,1]\r\n--    codigosAlergias 4  ==  [2]\r\n--    codigosAlergias 5  ==  [0,2]\r\n--    codigosAlergias 6  ==  [1,2]\r\ncodigosAlergias :: Int -> [Int]\r\ncodigosAlergias = aux [0..7]\r\n  where aux []     _             = []\r\n        aux (x:xs) n | odd n     = x : aux xs (n `div` 2)\r\n                     | otherwise = aux xs (n `div` 2)\r\n\r\n-- 3\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nalergias3 :: Int -> [Alergeno]\r\nalergias3 = map toEnum . codigosAlergias3\r\n\r\ncodigosAlergias3 :: Int -> [Int]\r\ncodigosAlergias3 n =\r\n  [x | (x,y) <- zip [0..7] (int2bin n), y == 1]\r\n\r\n-- (int2bin n) es la representaci\u00f3n binaria del n\u00famero n. Por ejemplo,\r\n--    int2bin 10  ==  [0,1,0,1]\r\n-- ya que 10 = 0*1 + 1*2 + 0*4 + 1*8\r\nint2bin :: Int -> [Int]\r\nint2bin n | n < 2     = [n]\r\n          | otherwise = n `rem` 2 : int2bin (n `div` 2)\r\n\r\n-- 4\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nalergias4 :: Int -> [Alergeno]\r\nalergias4 = map toEnum . codigosAlergias4\r\n\r\ncodigosAlergias4 :: Int -> [Int]\r\ncodigosAlergias4 n =\r\n  map fst (filter ((== 1) . snd) (zip  [0..7] (int2bin n)))\r\n\r\n-- 5\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nalergias5 :: Int -> [Alergeno]\r\nalergias5 = map (toEnum . fst)\r\n          . filter ((1 ==) . snd)\r\n          . zip [0..7]\r\n          . int2bin\r\n\r\n-- 6\u00aa soluci\u00f3n\r\n-- ===========\r\n\r\nalergias6 :: Int -> [Alergeno]\r\nalergias6 = aux alergenos\r\n  where aux []     _             = []\r\n        aux (x:xs) n | odd n     = x : aux xs (n `div` 2)\r\n                     | otherwise = aux xs (n `div` 2)\r\n\r\n-- alergenos es la lista de los alergenos. Por ejemplo.\r\n--    take 3 alergenos  ==  [Huevos,Cacahuetes,Mariscos]\r\nalergenos :: [Alergeno]\r\nalergenos = [minBound..maxBound]\r\n\r\n-- Comprobaci\u00f3n de equivalencia\r\n-- ============================\r\n\r\n-- La propiedad es\r\nprop_alergias :: Property\r\nprop_alergias =\r\n  forAll (arbitrary `suchThat` esValido) $ \\n ->\r\n  all (== alergias1 n)\r\n      [alergias2 n,\r\n       alergias3 n,\r\n       alergias4 n,\r\n       alergias5 n,\r\n       alergias6 n]\r\n  where esValido x = 1 <= x &#038;&#038; x <= 255\r\n\r\n-- La comprobaci\u00f3n es\r\n--    \u03bb> quickCheck prop_alergias\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> last (map alergias1 [1..255])\r\n--    [Huevos,Cacahuetes,Mariscos,Fresas,Tomates,Chocolate,Polen,Gatos]\r\n--    (0.02 secs, 1,657,912 bytes)\r\n--    \u03bb> last (map alergias2 [1..255])\r\n--    [Huevos,Cacahuetes,Mariscos,Fresas,Tomates,Chocolate,Polen,Gatos]\r\n--    (0.01 secs, 597,080 bytes)\r\n--    \u03bb> last (map alergias3 [1..255])\r\n--    [Huevos,Cacahuetes,Mariscos,Fresas,Tomates,Chocolate,Polen,Gatos]\r\n--    (0.01 secs, 597,640 bytes)\r\n--    \u03bb> last (map alergias4 [1..255])\r\n--    [Huevos,Cacahuetes,Mariscos,Fresas,Tomates,Chocolate,Polen,Gatos]\r\n--    (0.01 secs, 598,152 bytes)\r\n--    \u03bb> last (map alergias5 [1..255])\r\n--    [Huevos,Cacahuetes,Mariscos,Fresas,Tomates,Chocolate,Polen,Gatos]\r\n--    (0.01 secs, 596,888 bytes)\r\n<\/pre>\n<p>El c\u00f3digo se encuentra en [GitHub](https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Alergias.hs).<\/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>Para la determinaci\u00f3n de las alergia se utiliza los siguientes c\u00f3digos para los al\u00e9rgenos: Huevos &#8230;&#8230;.. 1 Cacahuetes &#8230;. 2 Mariscos &#8230;&#8230; 4 Fresas &#8230;&#8230;.. 8 Tomates &#8230;&#8230;. 16 Chocolate &#8230;.. 32 Polen &#8230;&#8230;&#8230; 64 Gatos &#8230;&#8230;&#8230; 128 As\u00ed, si Juan es al\u00e9rgico a los cacahuetes y al chocolate, su puntuaci\u00f3n es 34 (es decir,&#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":[483,8,498,30,26,38,338,80,71,10,538,537,92,11,6,31,16,88,539,40,146,503,87,9],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6894"}],"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=6894"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6894\/revisions"}],"predecessor-version":[{"id":6895,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6894\/revisions\/6895"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=6894"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=6894"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=6894"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}