{"id":7786,"date":"2022-09-10T09:23:44","date_gmt":"2022-09-10T07:23:44","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=7786"},"modified":"2022-09-10T09:23:44","modified_gmt":"2022-09-10T07:23:44","slug":"pfh-la-semana-en-exercitium-9-de-septiembre-de-2022","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/pfh-la-semana-en-exercitium-9-de-septiembre-de-2022\/","title":{"rendered":"PFH: La semana en Exercitium (9 de septiembre de 2022)"},"content":{"rendered":"<p>Esta semana he publicado en <a href=\"http:\/\/bit.ly\/2sqPtGs\">Exercitium<\/a> las soluciones de los siguientes problemas:<\/p>\n<ul>\n<li><a href=\"#ej1\">1. Intercambio de componentes de un par<\/a><\/li>\n<li><a href=\"#ej2\">2. Distancia entre dos puntos<\/a><\/li>\n<li><a href=\"#ej3\">3. Permutaci\u00f3n c\u00edclica<\/a><\/li>\n<li><a href=\"#ej4\">4. Mayor n\u00famero con dos d\u00edgitos dados<\/a><\/li>\n<li><a href=\"#ej5\">5. N\u00famero de ra\u00edces de la ecuaci\u00f3n de segundo grado<\/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. Intercambio de componentes de un par<\/h3>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   intercambia :: (a,b) -> (b,a)\n<\/pre>\n<p>tal que <code>(intercambia p)<\/code>  es el punto obtenido intercambiando las coordenadas del punto <code>p<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   intercambia (2,5)  ==  (5,2)\n   intercambia (5,2)  ==  (2,5)\n<\/pre>\n<p><b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport Test.QuickCheck\n\nintercambia :: (a,b) -> (b,a)\nintercambia (x,y) = (y,x)\n\n-- La propiedad es\nprop_intercambia :: (Int,Int) -> Bool\nprop_intercambia p = intercambia (intercambia p) == p\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_intercambia\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Intercambio_de_componentes_de_un_par.hs\">GitHub<\/a>.<\/p>\n<p><b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom typing import TypeVar\nfrom hypothesis import given, strategies as st\n\nA = TypeVar('A')\nB = TypeVar('B')\n\ndef intercambia(p: tuple[A, B]) -> tuple[B, A]:\n    (x, y) = p\n    return (y, x)\n\n# La propiedad de es\n@given(st.tuples(st.integers(), st.integers()))\ndef test_equiv_intercambia(p):\n    assert intercambia(intercambia(p)) == p\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q intercambio_de_componentes_de_un_par.py\n#    1 passed in 0.15s\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium-Python\/blob\/main\/src\/intercambio_de_componentes_de_un_par.py\">GitHub<\/a>.<\/p>\n<p><b>Comentarios<\/b><\/p>\n<ul>\n<li>En Haskell se pone el patr\u00f3n en los argumentos y en Python hay que extraerlos mediante un asignaci\u00f3n.<\/li>\n<\/ul>\n<p><a name=\"ej2\"><\/a><\/p>\n<h3>2. Distancia entre dos puntos<\/h3>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   distancia :: (Double,Double) -> (Double,Double) -> Double\n<\/pre>\n<p>tal que <code>(distancia p1 p2)<\/code> es la distancia entre los puntos <code>p1<\/code> y <code>p2<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   distancia (1,2) (4,6)  ==  5.0\n<\/pre>\n<p>Comprobar con QuickCheck que se verifica la propiedad triangular de la distancia; es decir, dados tres puntos <code>p1<\/code>, <code>p2<\/code> y <code>p3<\/code>, la distancia de <code>p1<\/code> a <code>p3<\/code> es menor o igual que la suma de la distancia de <code>p1<\/code> a <code>p2<\/code> y la de <code>p2<\/code> a <code>p3<\/code>.<\/p>\n<p><b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport Test.QuickCheck\n\ndistancia :: (Double,Double) -> (Double,Double) -> Double\ndistancia (x1,y1) (x2,y2) = sqrt((x1-x2)^2+(y1-y2)^2)\n\n-- La propiedad es\nprop_triangular :: (Double,Double) -> (Double,Double) -> (Double,Double)\n                -> Property\nprop_triangular p1 p2 p3 =\n    all acotado [p1, p2, p3] ==>\n    distancia p1 p3 <= distancia p1 p2 + distancia p2 p3\n    where acotado (x, y) = abs x < cota &#038;&#038; abs y < cota\n          cota = 2^30\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_triangular\n--    +++ OK, passed 100 tests.\n\n-- Nota: Por problemas de redondeo, la propiedad no se cumple en\n-- general. Por ejemplo,\n--    \u03bb> p1 = (0, 9147936743096483)\n--    \u03bb> p2 = (0, 3)\n--    \u03bb> p3 = (0, 2)\n--    \u03bb> distancia p1 p3 <= distancia p1 p2 + distancia p2 p3\n--    False\n--    \u03bb> distancia p1 p3\n--    9.147936743096482e15\n--    \u03bb> distancia p1 p2 + distancia p2 p3\n--    9.14793674309648e15\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Distancia_entre_dos_puntos.hs\">GitHub<\/a>.<\/p>\n<p><b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom math import sqrt\nfrom hypothesis import given, strategies as st\n\ndef distancia(p1: tuple[float, float],\n              p2: tuple[float, float]) -> float:\n    (x1, y1) = p1\n    (x2, y2) = p2\n    return sqrt((x1-x2)**2+(y1-y2)**2)\n\n# La propiedad es\ncota = 2 ** 30\n\n@given(st.tuples(st.integers(min_value=0, max_value=cota),\n                 st.integers(min_value=0, max_value=cota)),\n       st.tuples(st.integers(min_value=0, max_value=cota),\n                 st.integers(min_value=0, max_value=cota)),\n       st.tuples(st.integers(min_value=0, max_value=cota),\n                 st.integers(min_value=0, max_value=cota)))\ndef test_triangular(p1, p2, p3):\n    assert distancia(p1, p3) <= distancia(p1, p2) + distancia(p2, p3)\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q distancia_entre_dos_puntos.py\n#    1 passed in 0.38s\n\n# Nota: Por problemas de redondeo, la propiedad no se cumple en\n# general. Por ejemplo,\n#    \u03bb> p1 = (0, 9147936743096483)\n#    \u03bb> p2 = (0, 3)\n#    \u03bb> p3 = (0, 2)\n#    \u03bb> distancia(p1, p3) <= distancia(p1, p2) + distancia (p2. p3)\n#    False\n#    \u03bb> distancia(p1, p3)\n#    9147936743096482.0\n#    \u03bb> distancia(p1, p2) + distancia(p2, p3)\n#    9147936743096480.05\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium-Python\/blob\/main\/src\/distancia_entre_dos_puntos.py\">GitHub<\/a>.<\/p>\n<p><b>Comentarios<\/b><\/p>\n<ul>\n<li>La ra\u00edz cuadrada de <code>x<\/code> se escribe\n<ul>\n<li>en Haskell, como <code>sqrt x<\/code> y<\/li>\n<li>en Python, como <code>sqrt(x)<\/code> y hay que importarla del m\u00f3dulo <code>math<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><a name=\"ej3\"><\/a><\/p>\n<h3>3. Permutaci\u00f3n c\u00edclica<\/h3>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   ciclo :: [a] -> [a]\n<\/pre>\n<p>tal que <code>(ciclo xs)<\/code> es la lista obtenida permutando c\u00edclicamente los elementos de la lista <code>xs<\/code>, pasando el \u00faltimo elemento al principio de la lista. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   ciclo [2,5,7,9]  == [9,2,5,7]\n   ciclo []         == []\n   ciclo [2]        == [2]\n<\/pre>\n<p>Comprobar que la longitud es un invariante de la funci\u00f3n ciclo; es decir, la longitud de <code>(ciclo xs)<\/code> es la misma que la de <code>xs<\/code>.<\/p>\n<p><b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nimport Test.QuickCheck\n\nciclo :: [a] -> [a]\nciclo [] = []\nciclo xs = last xs : init xs\n\n-- La propiedad es\nprop_ciclo :: [Int] -> Bool\nprop_ciclo xs = length (ciclo xs) == length xs\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_ciclo\n--    +++ OK, passed 100 tests.\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Permutacion_ciclica.hs\">GitHub<\/a><\/p>\n<p><b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom typing import TypeVar\nfrom hypothesis import given, strategies as st\n\nA = TypeVar('A')\n\ndef ciclo(xs: list[A]) -> list[A]:\n    if xs:\n        return [xs[-1]] + xs[:-1]\n    return []\n\n# La propiedad de es\n@given(st.lists(st.integers()))\ndef test_equiv_ciclo(xs):\n    assert len(ciclo(xs)) == len(xs)\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q permutacion_ciclica.py\n#    1 passed in 0.39s\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium-Python\/blob\/main\/src\/permutacion_ciclica.py\">GitHub<\/a>.<\/p>\n<p><a name=\"ej4\"><\/a><\/p>\n<h3>4. Mayor n\u00famero con dos d\u00edgitos dados<\/h3>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   numeroMayor :: Int -> Int -> Int\n<\/pre>\n<p>tal que <code>(numeroMayor x y)<\/code> es el mayor n\u00famero de dos cifras que puede construirse con los d\u00edgitos <code>x<\/code> e <code>y<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   numeroMayor 2 5 ==  52\n   numeroMayor 5 2 ==  52\n<\/pre>\n<p><b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\n-- 1\u00aa definici\u00f3n:\nnumeroMayor1 :: Int -> Int -> Int\nnumeroMayor1 x y = 10 * max x y + min x y\n\n-- 2\u00aa definici\u00f3n:\nnumeroMayor2 :: Int -> Int -> Int\nnumeroMayor2 x y | x > y     = 10*x+y\n                 | otherwise = 10*y+x\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_numeroMayor :: Bool\nprop_numeroMayor =\n  and [numeroMayor1 x y == numeroMayor2 x y | x <- [0..9], y <- [0..9]]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> prop_numeroMayor\n--    True\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Mayor_numero_con_dos_digitos_dados.hs\">GitHub<\/a>.<\/p>\n<p><b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\n# 1\u00aa definici\u00f3n\ndef numeroMayor1(x: int, y: int) -> int:\n    return 10 * max(x, y) + min(x, y)\n\n# 2\u00aa definici\u00f3n\ndef numeroMayor2(x: int, y: int) -> int:\n    if x > y:\n        return 10 * x + y\n    return 10 * y + x\n\n# La propiedad de equivalencia de las definiciones es\ndef test_equiv_numeroMayor():\n    # type: () -> bool\n    return all(numeroMayor1(x, y) == numeroMayor2(x, y)\n               for x in range(10) for y in range(10))\n\n# La comprobaci\u00f3n es\n#    >>> test_equiv_numeroMayor()\n#    True\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium-Python\/blob\/main\/src\/mayor_numero_con_dos_digitos_dados.py\">GitHub<\/a>.<\/p>\n<p><a name=\"ej5\"><\/a><\/p>\n<h3>5. N\u00famero de ra\u00edces de la ecuaci\u00f3n de segundo grado<\/h3>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   numeroDeRaices :: (Num t, Ord t) => t -> t -> t -> Int\n<\/pre>\n<p>tal que <code>(numeroDeRaices a b c)<\/code> es el n\u00famero de ra\u00edces reales de la ecuaci\u00f3n <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=ax%5E2+%2B+bx+%2B+c+%3D+0&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"ax^2 + bx + c = 0\" class=\"latex\" \/>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   numeroDeRaices 2 0 3    ==  0\n   numeroDeRaices 4 4 1    ==  1\n   numeroDeRaices 5 23 12  ==  2\n<\/pre>\n<p><b>Soluciones en Haskell<\/b><\/p>\n<pre lang=\"haskell\">\nnumeroDeRaices :: (Num t, Ord t) => t -> t -> t -> Int\nnumeroDeRaices a b c | d < 0     = 0\n                     | d == 0    = 1\n                     | otherwise = 2\n  where d = b^2-4*a*c\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Numero_de_raices_de_la_ecuacion_de_segundo_grado.hs\">GitHub<\/a>.<\/p>\n<p><b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\ndef numeroDeRaices(a: float, b: float, c: float) -> float:\n    d = b ** 2 - 4 * a * c\n    if d < 0:\n        return 0\n    if d == 0:\n        return 1\n    return 2\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium-Python\/blob\/main\/src\/numero_de_raices_de_la_ecuacion_de_segundo_grado.\u1ef3\">GitHub<\/a>.<\/p>\n<p><b>Comentarios<\/b><\/p>\n<ul>\n<li>En Haskell se usa un entorno local con <code>where d = b^2-4*a*c<\/code> y en Python se usa la asignaci\u00f3n <code>d = b ** 2 - 4 * a * c<\/code>.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Esta semana he publicado en Exercitium las soluciones de los siguientes problemas: 1. Intercambio de componentes de un par 2. Distancia entre dos puntos 3. Permutaci\u00f3n c\u00edclica 4. Mayor n\u00famero con dos d\u00edgitos dados 5. N\u00famero de ra\u00edces de la ecuaci\u00f3n de segundo grado A continuaci\u00f3n se muestran las soluciones.<\/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\/7786"}],"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=7786"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7786\/revisions"}],"predecessor-version":[{"id":7787,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7786\/revisions\/7787"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=7786"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=7786"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=7786"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}