{"id":7916,"date":"2023-03-25T12:31:53","date_gmt":"2023-03-25T11:31:53","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=7916"},"modified":"2023-03-28T12:57:28","modified_gmt":"2023-03-28T10:57:28","slug":"25-mar-23","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/25-mar-23\/","title":{"rendered":"La semana en Exercitium (25 de marzo de 2023)"},"content":{"rendered":"<p>Esta semana he publicado en <a href=\"http:\/\/bit.ly\/2sqPtGs\">Exercitium<\/a> las soluciones de los  siguientes problemas sobre el <a href=\"https:\/\/bit.ly\/3HbB7fo\">tipo abstracto de datos de los  conjuntos<\/a><\/p>\n<ul>\n<li><a href=\"#ej1\">1. Partici\u00f3n de un conjunto seg\u00fan una propiedad<\/a><\/li>\n<li><a href=\"#ej2\">2. Partici\u00f3n seg\u00fan un n\u00famero<\/a><\/li>\n<li><a href=\"#ej3\">3. Aplicaci\u00f3n de una funci\u00f3n a los elementos de un conjunto<\/a><\/li>\n<li><a href=\"#ej4\">4. Todos los elementos verifican una propiedad<\/a><\/li>\n<li><a href=\"#ej5\">5. Algunos elementos verifican una propiedad<\/a><\/li>\n<\/ul>\n<p>A continuaci\u00f3n se muestran las soluciones.<br \/>\n<!--more--><br \/>\n<a name=\"ej1\"><\/a><\/p>\n<h3>1. TAD de los conjuntos: Partici\u00f3n de un conjunto seg\u00fan una propiedad<\/h3>\n<p>Utilizando el <a href=\"https:\/\/bit.ly\/3HbB7fo\">tipo abstracto de datos de los conjuntos<\/a> definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   particion :: Ord a => (a -> Bool) -> Conj a -> (Conj a, Conj a)\n<\/pre>\n<p>tal que <code>particion c<\/code> es el par formado por dos conjuntos: el de los elementos de <code>c<\/code> que verifican <code>p<\/code> y el de los elementos que no lo verifican. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> ej = inserta 5 (inserta 4 (inserta 7 (inserta 2 vacio)))\n   \u03bb> particion even ej\n   ({2, 4},{5, 7})\n<\/pre>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport TAD.Conjunto (Conj, vacio, inserta)\nimport TAD_Transformaciones_conjuntos_listas (conjuntoAlista, listaAconjunto)\nimport TAD_Subconjunto_por_propiedad (filtra)\nimport Data.List (partition)\nimport Test.QuickCheck.HigherOrder\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nparticion :: Ord a => (a -> Bool) -> Conj a -> (Conj a, Conj a)\nparticion p c = (filtra p c, filtra (not . p) c)\n\n-- La funci\u00f3n filtra est\u00e1 definida en el ejercicio\n-- \"Subconjunto determinado por una propiedad\" que se encuentra en\n-- https:\/\/bit.ly\/3lplFoV\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nparticion2 :: Ord a => (a -> Bool) -> Conj a -> (Conj a, Conj a)\nparticion2 p c = (listaAconjunto xs, listaAconjunto ys)\n  where\n    (xs, ys) = partition p (conjuntoAlista c)\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_particion :: (Int -> Bool) -> [Int] -> Bool\nprop_particion p xs =\n  particion p c == particion2 p c\n  where c = listaAconjunto xs\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck' prop_particion\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom __future__ import annotations\n\nfrom abc import abstractmethod\nfrom copy import deepcopy\nfrom typing import Callable, Protocol, TypeVar\n\nfrom hypothesis import given\n\nfrom src.TAD.conjunto import (Conj, conjuntoAleatorio, elimina, esVacio,\n                              inserta, menor, vacio)\nfrom src.TAD_Subconjunto_por_propiedad import filtra\n\nclass Comparable(Protocol):\n    @abstractmethod\n    def __lt__(self: A, otro: A) -> bool:\n        pass\n\nA = TypeVar('A', bound=Comparable)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\ndef particion(p: Callable[[A], bool],\n              c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    return (filtra(p, c), filtra(lambda x: not p(x), c))\n\n# La funci\u00f3n filtra est\u00e1 definida en el ejercicio\n# \"Subconjunto determinado por una propiedad\" que se encuentra en\n# https:\/\/bit.ly\/3lplFoV\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef particion2Aux(p: Callable[[A], bool],\n                  c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    r: Conj[A] = vacio()\n    s: Conj[A] = vacio()\n    while not esVacio(c):\n        mc = menor(c)\n        c = elimina(mc, c)\n        if p(mc):\n            r = inserta(mc, r)\n        else:\n            s = inserta(mc, s)\n    return (r, s)\n\ndef particion2(p: Callable[[A], bool],\n               c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    _c = deepcopy(c)\n    return particion2Aux(p, _c)\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef particion3Aux(p: Callable[[A], bool],\n                  c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    r: Conj[A] = Conj()\n    s: Conj[A] = Conj()\n    while not c.esVacio():\n        mc = c.menor()\n        c.elimina(mc)\n        if p(mc):\n            r.inserta(mc)\n        else:\n            s.inserta(mc)\n    return (r, s)\n\ndef particion3(p: Callable[[A], bool],\n               c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    _c = deepcopy(c)\n    return particion3Aux(p, _c)\n\n# Comprobaci\u00f3n de equivalencia de las definiciones\n# ================================================\n\n# La propiedad es\n@given(c=conjuntoAleatorio())\ndef test_particion(c: Conj[int]) -> None:\n    r = particion(lambda x: x % 2 == 0, c)\n    assert particion2(lambda x: x % 2 == 0, c) == r\n    assert particion3(lambda x: x % 2 == 0, c) == r\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q TAD_Particion_por_una_propiedad.py\n#    1 passed in 0.28s\n<\/pre>\n<p><a name=\"ej2\"><\/a><\/p>\n<h3>2. TAD de los conjuntos: Partici\u00f3n seg\u00fan un n\u00famero<\/h3>\n<p>Utilizando el <a href=\"https:\/\/bit.ly\/3HbB7fo\">tipo abstracto de datos de los conjuntos<\/a> definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   divide :: (Ord a) => a-> Conj a -> (Conj a, Conj a)\n<\/pre>\n<p>tal que <code>divide x c<\/code> es el par formado por dos subconjuntos de <code>c<\/code>: el de los elementos menores o iguales que <code>x<\/code> y el de los mayores que <code>x<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> divide 5 (inserta 7 (inserta 2 (inserta 8 vacio)))\n   ({2},{7, 8})\n<\/pre>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport TAD.Conjunto (Conj, vacio, inserta, esVacio, menor, elimina)\nimport TAD_Particion_por_una_propiedad (particion)\nimport Test.QuickCheck\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\ndivide :: Ord a => a-> Conj a -> (Conj a, Conj a)\ndivide x c\n  | esVacio c = (vacio, vacio)\n  | mc <= x   = (inserta mc c1, c2)\n  | otherwise = (c1, inserta mc c2)\n  where\n    mc       = menor c\n    rc       = elimina mc c\n    (c1, c2) = divide x rc\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\ndivide2 :: Ord a => a-> Conj a -> (Conj a, Conj a)\ndivide2 x = particion (<= x)\n\n-- La funci\u00f3n particion est\u00e1 definida en el ejercicio\n-- \"Partici\u00f3n de un conjunto seg\u00fan una propiedad\" que se encuentra en\n-- https:\/\/bit.ly\/3YCOah5\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_divide :: Int -> Conj Int -> Bool\nprop_divide x c =\n  divide x c == divide2 x c\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_divide\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom __future__ import annotations\n\nfrom abc import abstractmethod\nfrom copy import deepcopy\nfrom typing import Protocol, TypeVar\n\nfrom hypothesis import given\nfrom hypothesis import strategies as st\n\nfrom src.TAD.conjunto import (Conj, conjuntoAleatorio, elimina, esVacio,\n                              inserta, menor, vacio)\nfrom src.TAD_Particion_por_una_propiedad import particion\n\nclass Comparable(Protocol):\n    @abstractmethod\n    def __lt__(self: A, otro: A) -> bool:\n        pass\n\nA = TypeVar('A', bound=Comparable)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\ndef divide(x: A, c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    if esVacio(c):\n        return (vacio(), vacio())\n    mc = menor(c)\n    rc = elimina(mc, c)\n    (c1, c2) = divide(x, rc)\n    if mc <= x:\n        return (inserta(mc, c1), c2)\n    return (c1, inserta(mc, c2))\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef divide2(x: A, c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    return particion(lambda y: y <= x, c)\n\n# La funci\u00f3n particion est\u00e1 definida en el ejercicio\n# \"Partici\u00f3n de un conjunto seg\u00fan una propiedad\" que se encuentra en\n# https:\/\/bit.ly\/3YCOah5\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef divide3Aux(x: A, c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    r: Conj[A] = vacio()\n    s: Conj[A] = vacio()\n    while not esVacio(c):\n        mc = menor(c)\n        c = elimina(mc, c)\n        if mc <= x:\n            r = inserta(mc, r)\n        else:\n            s = inserta(mc, s)\n    return (r, s)\n\ndef divide3(x: A, c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    _c = deepcopy(c)\n    return divide3Aux(x, _c)\n\n# 4\u00aa soluci\u00f3n\n# ===========\n\ndef divide4Aux(x: A, c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    r: Conj[A] = Conj()\n    s: Conj[A] = Conj()\n    while not c.esVacio():\n        mc = c.menor()\n        c.elimina(mc)\n        if mc <= x:\n            r.inserta(mc)\n        else:\n            s.inserta(mc)\n    return (r, s)\n\ndef divide4(x: A, c: Conj[A]) -> tuple[Conj[A], Conj[A]]:\n    _c = deepcopy(c)\n    return divide4Aux(x, _c)\n\n# Comprobaci\u00f3n de equivalencia de las definiciones\n# ================================================\n\n# La propiedad es\n@given(x=st.integers(), c=conjuntoAleatorio())\ndef test_particion(x: int, c: Conj[int]) -> None:\n    r = divide(x, c)\n    assert divide2(x, c) == r\n    assert divide3(x, c) == r\n    assert divide4(x, c) == r\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q TAD_Particion_segun_un_numero.py\n#    1 passed in 0.30s\n<\/pre>\n<p><a name=\"ej3\"><\/a><\/p>\n<h3>3. TAD de los conjuntos: Aplicaci\u00f3n de una funci\u00f3n a los elementos de un conjunto<\/h3>\n<p>Utilizando el <a href=\"https:\/\/bit.ly\/3HbB7fo\">tipo abstracto de datos de los conjuntos<\/a> definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   mapC :: (Ord a, Ord b) => (a -> b) -> Conj a -> Conj b\n<\/pre>\n<p>tal que <code>map f c<\/code> es el conjunto formado por las im\u00e1genes de los elementos del conjunto <code>c<\/code>, mediante la aplicaci\u00f3n <code>f<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> mapC (*2) (inserta 3 (inserta 1 vacio))\n   {2, 6}\n<\/pre>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport TAD.Conjunto (Conj, vacio, inserta, esVacio, menor, elimina)\nimport TAD_Transformaciones_conjuntos_listas (conjuntoAlista, listaAconjunto)\nimport Test.QuickCheck.HigherOrder\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nmapC :: (Ord a, Ord b) => (a -> b) -> Conj a -> Conj b\nmapC f c\n  | esVacio c = vacio\n  | otherwise = inserta (f mc) (mapC f rc)\n  where mc = menor c\n        rc = elimina mc c\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nmapC2 :: (Ord a, Ord b) => (a -> b) -> Conj a -> Conj b\nmapC2 f c = listaAconjunto (map f (conjuntoAlista c))\n\n-- Las funciones conjuntoAlista y listaAconjunto est\u00e1 definida en el\n-- ejercicio Transformaciones entre conjuntos y listas\" que se encuentra\n-- en https:\/\/bit.ly\/3RexzxH\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_mapC :: (Int -> Int) -> [Int] -> Bool\nprop_mapC f xs =\n  mapC f c == mapC2 f c\n  where c = listaAconjunto xs\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck' prop_mapC\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom __future__ import annotations\n\nfrom abc import abstractmethod\nfrom copy import deepcopy\nfrom typing import Callable, Protocol, TypeVar\n\nfrom hypothesis import given\n\nfrom src.TAD.conjunto import (Conj, conjuntoAleatorio, elimina, esVacio,\n                              inserta, menor, vacio)\nfrom src.TAD_Transformaciones_conjuntos_listas import (conjuntoAlista,\n                                                       listaAconjunto)\n\nclass Comparable(Protocol):\n    @abstractmethod\n    def __lt__(self: A, otro: A) -> bool:\n        pass\n\nA = TypeVar('A', bound=Comparable)\nB = TypeVar('B', bound=Comparable)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\ndef mapC(f: Callable[[A], B], c: Conj[A]) -> Conj[B]:\n    if esVacio(c):\n        return vacio()\n    mc = menor(c)\n    rc = elimina(mc, c)\n    return inserta(f(mc), mapC(f, rc))\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef mapC2(f: Callable[[A], B], c: Conj[A]) -> Conj[B]:\n    return listaAconjunto(list(map(f, conjuntoAlista(c))))\n\n# Las funciones conjuntoAlista y listaAconjunto est\u00e1 definida en el\n# ejercicio Transformaciones entre conjuntos y listas\" que se encuentra\n# en https:\/\/bit.ly\/3RexzxH\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef mapC3Aux(f: Callable[[A], B], c: Conj[A]) -> Conj[B]:\n    r: Conj[B] = vacio()\n    while not esVacio(c):\n        mc = menor(c)\n        c = elimina(mc, c)\n        r = inserta(f(mc), r)\n    return r\n\ndef mapC3(f: Callable[[A], B], c: Conj[A]) -> Conj[B]:\n    _c = deepcopy(c)\n    return mapC3Aux(f, _c)\n\n# 4\u00aa soluci\u00f3n\n# ===========\n\ndef mapC4Aux(f: Callable[[A], B], c: Conj[A]) -> Conj[B]:\n    r: Conj[B] = Conj()\n    while not c.esVacio():\n        mc = c.menor()\n        c.elimina(mc)\n        r.inserta(f(mc))\n    return r\n\ndef mapC4(f: Callable[[A], B], c: Conj[A]) -> Conj[B]:\n    _c = deepcopy(c)\n    return mapC4Aux(f, _c)\n\n# Comprobaci\u00f3n de equivalencia de las definiciones\n# ================================================\n\n# La propiedad es\n@given(c=conjuntoAleatorio())\ndef test_mapPila(c: Conj[int]) -> None:\n    r = mapC(lambda x: 2 * x, c)\n    assert mapC2(lambda x: 2 * x, c) == r\n    assert mapC3(lambda x: 2 * x, c) == r\n    assert mapC4(lambda x: 2 * x, c) == r\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q TAD_mapC.py\n#    1 passed in 0.29s\n<\/pre>\n<p><a name=\"ej4\"><\/a><\/p>\n<h3>4. TAD de los conjuntos: Todos los elementos verifican una propiedad<\/h3>\n<p>Utilizando el <a href=\"https:\/\/bit.ly\/3HbB7fo\">tipo abstracto de datos de los conjuntos<\/a> definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   todos :: Ord a => (a -> Bool) -> Conj a -> Bool\n<\/pre>\n<p>tal que <code>todos p c<\/code> se verifica si todos los elemsntos de <code>c<\/code> verifican el predicado <code>p<\/code>.  Por ejemplo,<\/p>\n<pre lang=\"text\">\n   todos even (inserta 4 (inserta 6 vacio))  ==  True\n   todos even (inserta 4 (inserta 7 vacio))  ==  False\n<\/pre>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport TAD.Conjunto (Conj, vacio, inserta, esVacio, menor, elimina)\nimport TAD_Transformaciones_conjuntos_listas (conjuntoAlista, listaAconjunto)\nimport Test.QuickCheck.HigherOrder\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\ntodos :: Ord a => (a -> Bool) -> Conj a -> Bool\ntodos p c\n  | esVacio c = True\n  | otherwise = p mc && todos p rc\n  where mc = menor c\n        rc = elimina mc c\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\ntodos2 :: Ord a => (a -> Bool) -> Conj a -> Bool\ntodos2 p c = all p (conjuntoAlista c)\n\n-- La funci\u00f3n conjuntoAlista est\u00e1 definida en el ejercicio\n-- \"Transformaciones entre conjuntos y listas\" que se encuentra\n-- en https:\/\/bit.ly\/3RexzxH\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_todos :: (Int -> Bool) -> [Int] -> Bool\nprop_todos p xs =\n  todos p c == todos2 p c\n  where c = listaAconjunto xs\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck' prop_todos\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom __future__ import annotations\n\nfrom abc import abstractmethod\nfrom copy import deepcopy\nfrom typing import Callable, Protocol, TypeVar\n\nfrom hypothesis import given\n\nfrom src.TAD.conjunto import (Conj, conjuntoAleatorio, elimina, esVacio,\n                              inserta, menor, vacio)\nfrom src.TAD_Transformaciones_conjuntos_listas import conjuntoAlista\n\nclass Comparable(Protocol):\n    @abstractmethod\n    def __lt__(self: A, otro: A) -> bool:\n        pass\n\nA = TypeVar('A', bound=Comparable)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\ndef todos(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    if esVacio(c):\n        return True\n    mc = menor(c)\n    rc = elimina(mc, c)\n    return p(mc) and todos(p, rc)\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef todos2(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    return all(p(x) for x in conjuntoAlista(c))\n\n# La funci\u00f3n conjuntoAlista est\u00e1 definida en el ejercicio\n# \"Transformaciones entre conjuntos y listas\" que se encuentra\n# en https:\/\/bit.ly\/3RexzxH\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef todos3Aux(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    while not esVacio(c):\n        mc = menor(c)\n        c = elimina(mc, c)\n        if not p(mc):\n            return False\n    return True\n\ndef todos3(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    _c = deepcopy(c)\n    return todos3Aux(p, _c)\n\n# 4\u00aa soluci\u00f3n\n# ===========\n\ndef todos4Aux(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    while not c.esVacio():\n        mc = c.menor()\n        c.elimina(mc)\n        if not p(mc):\n            return False\n    return True\n\ndef todos4(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    _c = deepcopy(c)\n    return todos4Aux(p, _c)\n\n# Comprobaci\u00f3n de equivalencia de las definiciones\n# ================================================\n\n# La propiedad es\n@given(c=conjuntoAleatorio())\ndef test_todos(c: Conj[int]) -> None:\n    r = todos(lambda x: x % 2 == 0, c)\n    assert todos2(lambda x: x % 2 == 0, c) == r\n    assert todos3(lambda x: x % 2 == 0, c) == r\n    assert todos4(lambda x: x % 2 == 0, c) == r\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q TAD_TodosVerificanConj.py\n#    1 passed in 0.28s\n<\/pre>\n<p><a name=\"ej5\"><\/a><\/p>\n<h3>5. TAD de los conjuntos: Algunos elementos verifican una propiedad<\/h3>\n<p>Utilizando el <a href=\"https:\/\/bit.ly\/3HbB7fo\">tipo abstracto de datos de los conjuntos<\/a> definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   algunos :: Ord a => (a -> Bool) -> Conj a -> Bool\n<\/pre>\n<p>tal que <code>algunos p c<\/code> se verifica si alg\u00fan elemento de <code>c<\/code> verifica el predicado <code>p<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   algunos even (inserta 4 (inserta 7 vacio))  ==  True\n   algunos even (inserta 3 (inserta 7 vacio))  ==  False\n<\/pre>\n<p><b>Soluciones<\/b><\/p>\n<p>A continuaci\u00f3n se muestran las <a href=\"#haskell\">soluciones en Haskell<\/a> y las <a href=\"#python\">soluciones en Python<\/a>.<\/p>\n<p><a name=\"haskell\"><\/a><br \/>\n<b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport TAD.Conjunto (Conj, vacio, inserta, esVacio, menor, elimina)\nimport TAD_Transformaciones_conjuntos_listas (conjuntoAlista, listaAconjunto)\nimport Test.QuickCheck.HigherOrder\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nalgunos :: Ord a => (a -> Bool) -> Conj a -> Bool\nalgunos p c\n  | esVacio c = False\n  | otherwise = p mc || algunos p rc\n  where mc = menor c\n        rc = elimina mc c\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nalgunos2 :: Ord a => (a -> Bool) -> Conj a -> Bool\nalgunos2 p c = any p (conjuntoAlista c)\n\n-- La funci\u00f3n conjuntoAlista est\u00e1 definida en el ejercicio\n-- \"Transformaciones entre conjuntos y listas\" que se encuentra\n-- en https:\/\/bit.ly\/3RexzxH\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_algunos :: (Int -> Bool) -> [Int] -> Bool\nprop_algunos p xs =\n  algunos p c == algunos2 p c\n  where c = listaAconjunto xs\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck' prop_algunos\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom __future__ import annotations\n\nfrom abc import abstractmethod\nfrom copy import deepcopy\nfrom typing import Callable, Protocol, TypeVar\n\nfrom hypothesis import given\n\nfrom src.TAD.conjunto import (Conj, conjuntoAleatorio, elimina, esVacio,\n                              inserta, menor, vacio)\nfrom src.TAD_Transformaciones_conjuntos_listas import conjuntoAlista\n\nclass Comparable(Protocol):\n    @abstractmethod\n    def __lt__(self: A, otro: A) -> bool:\n        pass\n\nA = TypeVar('A', bound=Comparable)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\ndef algunos(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    if esVacio(c):\n        return False\n    mc = menor(c)\n    rc = elimina(mc, c)\n    return p(mc) or algunos(p, rc)\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef algunos2(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    return any(p(x) for x in conjuntoAlista(c))\n\n# La funci\u00f3n conjuntoAlista est\u00e1 definida en el ejercicio\n# \"Transformaciones entre conjuntos y listas\" que se encuentra\n# en https:\/\/bit.ly\/3RexzxH\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef algunos3Aux(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    while not esVacio(c):\n        mc = menor(c)\n        c = elimina(mc, c)\n        if p(mc):\n            return True\n    return False\n\ndef algunos3(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    _c = deepcopy(c)\n    return algunos3Aux(p, _c)\n\n# 4\u00aa soluci\u00f3n\n# ===========\n\ndef algunos4Aux(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    while not c.esVacio():\n        mc = c.menor()\n        c.elimina(mc)\n        if p(mc):\n            return True\n    return False\n\ndef algunos4(p: Callable[[A], bool], c: Conj[A]) -> bool:\n    _c = deepcopy(c)\n    return algunos4Aux(p, _c)\n\n# Comprobaci\u00f3n de equivalencia de las definiciones\n# ================================================\n\n# La propiedad es\n@given(c=conjuntoAleatorio())\ndef test_algunos(c: Conj[int]) -> None:\n    r = algunos(lambda x: x % 2 == 0, c)\n    assert algunos2(lambda x: x % 2 == 0, c) == r\n    assert algunos3(lambda x: x % 2 == 0, c) == r\n    assert algunos4(lambda x: x % 2 == 0, c) == r\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q TAD_AlgunosVerificanConj.py\n#    1 passed in 0.28s\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Esta semana he publicado en Exercitium las soluciones de los siguientes problemas sobre el tipo abstracto de datos de los conjuntos 1. Partici\u00f3n de un conjunto seg\u00fan una propiedad 2. Partici\u00f3n seg\u00fan un n\u00famero 3. Aplicaci\u00f3n de una funci\u00f3n a los elementos de un conjunto 4. Todos los elementos verifican una propiedad 5. Algunos elementos&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","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":[337],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7916"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=7916"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7916\/revisions"}],"predecessor-version":[{"id":7917,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7916\/revisions\/7917"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=7916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=7916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=7916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}