{"id":6853,"date":"2022-03-31T06:00:50","date_gmt":"2022-03-31T04:00:50","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=6853"},"modified":"2022-04-07T07:41:02","modified_gmt":"2022-04-07T05:41:02","slug":"familias-de-numeros-con-algun-digito-en-comun","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/familias-de-numeros-con-algun-digito-en-comun\/","title":{"rendered":"Familias de n\u00fameros con alg\u00fan d\u00edgito en com\u00fan"},"content":{"rendered":"<p>Una familia de n\u00fameros es una lista de n\u00fameros tal que todos tienen la misma cantidad de d\u00edgitos y, adem\u00e1s, dichos n\u00fameros tienen al menos un d\u00edgito com\u00fan.<\/p>\n<p>Por ejemplo, los n\u00fameros 72, 32, 25 y 22 pertenecen a la misma familia ya que son n\u00fameros de dos d\u00edgitos y todos tienen el d\u00edgito 2, mientras que los n\u00fameros 123, 245 y 568 no pertenecen a la misma familia, ya que no hay un d\u00edgito que aparezca en los tres n\u00fameros.<\/p>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   esFamilia :: [Integer] -> Bool\n<\/pre>\n<p>tal que <code>(esFamilia ns)<\/code> se verifica si <code>ns<\/code> es una familia de n\u00fameros. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   esFamilia [72, 32, 25, 22]  ==  True\n   esFamilia [123,245,568]     ==  False\n   esFamilia [72, 32, 25, 223] ==  False\n   esFamilia [56]              ==  True\n   esFamilia []                ==  True\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.List (intersect, nub)\nimport Test.QuickCheck (quickCheck)\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nesFamilia1 :: [Integer] -> Bool\nesFamilia1 [] = True\nesFamilia1 ns =\n  igualNumeroElementos dss && tieneElementoComun dss\n  where dss = map show ns\n\n-- (igualNumeroElementos xss) se verifica si todas las listas de xss\n-- tienen el mismo n\u00famero de elementos. Por ejemplo,\n--    igualNumeroElementos [[1,3],[2,2],[4,9]]    ==  True\n--    igualNumeroElementos [[1,3],[2,1,2],[4,9]]  ==  False\nigualNumeroElementos :: [[a]] -> Bool\nigualNumeroElementos xss =\n  iguales (map length xss)\n\n-- (iguales xs) se verifica si todos los elementos de xs son\n-- iguales. Por ejemplo,\n--    iguales [3,3,3,3]  ==  True\n--    iguales [3,3,7,3]  ==  False\niguales :: Eq a => [a] -> Bool\niguales []     = True\niguales (x:xs) = all (==x) xs\n\n-- (tieneElementoComun xss) se verifican si todas las listas de xss\n-- tienen alg\u00fan elemento com\u00fan. Por ejemplo,\n--    tieneElementoComun [[1,2],[2,3],[4,2,7]]  ==  True\n--    tieneElementoComun [[1,2],[2,3],[4,3,7]]  ==  False\ntieneElementoComun :: Eq a => [[a]] -> Bool\ntieneElementoComun []       = False\ntieneElementoComun (xs:xss) = any (`esElementoComun` xss) xs\n\n-- (esElementoComun x yss) se verifica si x pertenece a todos los\n-- elementos de yss. Por ejemplo,\n--    esElementoComun 2 [[1,2],[2,3],[4,2,7]]  ==  True\n--    esElementoComun 2 [[1,2],[2,3],[4,3,7]]  ==  False\nesElementoComun :: Eq a => a -> [[a]] -> Bool\nesElementoComun x = all (x `elem`)\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nesFamilia2 :: [Integer] -> Bool\nesFamilia2 [] = True\nesFamilia2 ns =\n  igualNumeroElementos2 dss && tieneElementoComun2 dss\n  where dss = map show ns\n\nigualNumeroElementos2 :: [[a]] -> Bool\nigualNumeroElementos2 xss =\n  length (nub (map length xss)) == 1\n\ntieneElementoComun2 :: Eq a => [[a]] -> Bool\ntieneElementoComun2 xss =\n  not (null (foldl1 intersect xss))\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\nesFamilia3 :: [Integer] -> Bool\nesFamilia3 [] = True\nesFamilia3 ns =\n  igualNumeroElementos3 dss && tieneElementoComun3 dss\n  where dss = map show ns\n\nigualNumeroElementos3 :: [[a]] -> Bool\nigualNumeroElementos3 = ((==1) . length) . nub . map length\n\ntieneElementoComun3 :: Eq a => [[a]] -> Bool\ntieneElementoComun3 = (not . null) . foldl1 intersect\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_esFamilia :: [Integer] -> Bool\nprop_esFamilia xss =\n  all (== esFamilia1 xss)\n      [esFamilia2 xss,\n       esFamilia3 xss]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_esFamilia\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> esFamilia1 [10^6..4*10^6]\n--    False\n--    (1.85 secs, 1,931,162,984 bytes)\n--    \u03bb> esFamilia2 [10^6..4*10^6]\n--    False\n--    (2.31 secs, 2,288,177,752 bytes)\n--    \u03bb> esFamilia3 [10^6..4*10^6]\n--    False\n--    (2.23 secs, 2,288,177,864 bytes)\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Familias_de_numeros_con_algun_digito_en_comun.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\/_uOlyfzppVc\" 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>Una familia de n\u00fameros es una lista de n\u00fameros tal que todos tienen la misma cantidad de d\u00edgitos y, adem\u00e1s, dichos n\u00fameros tienen al menos un d\u00edgito com\u00fan. Por ejemplo, los n\u00fameros 72, 32, 25 y 22 pertenecen a la misma familia ya que son n\u00fameros de dos d\u00edgitos y todos tienen el d\u00edgito 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":[2],"tags":[41,163,498,26,522,270,28,10,181,24,141,11,33,146],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6853"}],"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=6853"}],"version-history":[{"count":3,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6853\/revisions"}],"predecessor-version":[{"id":6889,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6853\/revisions\/6889"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=6853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=6853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=6853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}