{"id":7932,"date":"2023-05-06T11:39:19","date_gmt":"2023-05-06T09:39:19","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=7932"},"modified":"2023-05-06T11:39:19","modified_gmt":"2023-05-06T09:39:19","slug":"06-may-23","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/06-may-23\/","title":{"rendered":"La semana en Exercitium (6 de mayo 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\/3KwqXYu\">tipo abstracto de los polinomios<\/a>.<\/p>\n<ul>\n<li><a href=\"#ej1\">1. Comprobaci\u00f3n de ra\u00edces de polinomios<\/a><\/li>\n<li><a href=\"#ej2\">2. Derivada de un polinomio<\/a><\/li>\n<li><a href=\"#ej3\">3. Resta de polinomios<\/a><\/li>\n<li><a href=\"#ej4\">4. Potencia de un polinomio<\/a><\/li>\n<li><a href=\"#ej5\">5. Integral de un polinomio<\/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. Comprobaci\u00f3n de ra\u00edces de polinomios<\/h3>\n<p>Usando el <a href=\"https:\/\/bit.ly\/3KwqXYu\">tipo abstracto de los polinomios<\/a>,<br \/>\ndefinir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   esRaiz :: (Num a, Eq a) => a -> Polinomio a -> Bool\n<\/pre>\n<p>tal que <code>esRaiz c p<\/code> se verifica si <code>c<\/code> es una raiz del polinomio <code>p<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> ejPol = consPol 4 6 (consPol 1 2 polCero)\n   \u03bb> ejPol\n   6*x^4 + 2*x\n   \u03bb> esRaiz 0 ejPol\n   True\n   \u03bb> esRaiz 1 ejPol\n   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.Polinomio (Polinomio, polCero, consPol)\nimport Pol_Valor_de_un_polinomio_en_un_punto (valor)\n\nesRaiz :: (Num a, Eq a) => a -> Polinomio a -> Bool\nesRaiz c p = valor p c == 0\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom typing import TypeVar\n\nfrom src.Pol_Valor_de_un_polinomio_en_un_punto import valor\nfrom src.TAD.Polinomio import Polinomio, consPol, polCero\n\nA = TypeVar('A', int, float, complex)\n\ndef esRaiz(c: A, p: Polinomio[A]) -> bool:\n    return valor(p, c) == 0\n<\/pre>\n<p><a name=\"ej2\"><\/a><\/p>\n<h3>2. Derivada de un polinomio<\/h3>\n<p>Usando el <a href=\"https:\/\/bit.ly\/3KwqXYu\">tipo abstracto de los polinomios<\/a>, definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   derivada :: (Eq a, Num a) => Polinomio a -> Polinomio a\n<\/pre>\n<p>tal que <code>derivada p<\/code> es la derivada del polinomio <code>p<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> ejPol = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero))\n   \u03bb> ejPol\n   x^5 + 5*x^2 + 4*x\n   \u03bb> derivada ejPol\n   5*x^4 + 10*x + 4\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.Polinomio (Polinomio, polCero, consPol, grado, coefLider,\n                      restoPol)\nimport Pol_Suma_de_polinomios (sumaPol)\nimport Test.QuickCheck\n\nderivada :: (Eq a, Num a) => Polinomio a -> Polinomio a\nderivada p\n  | n == 0     = polCero\n  | otherwise  = consPol (n-1) (b * fromIntegral n) (derivada r)\n  where n = grado p\n        b = coefLider p\n        r = restoPol p\n\n-- Propiedad. La derivada de la suma es la suma de las derivadas.\nprop_derivada :: Polinomio Int -> Polinomio Int -> Bool\nprop_derivada p q =\n  derivada (sumaPol p q) == sumaPol (derivada p) (derivada q)\n\n-- Comprobaci\u00f3n\n--    \u03bb> quickCheck prop_derivada\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 typing import TypeVar\n\nfrom hypothesis import given\n\nfrom src.Pol_Suma_de_polinomios import sumaPol\nfrom src.TAD.Polinomio import (Polinomio, coefLider, consPol, grado, polCero,\n                               polinomioAleatorio, restoPol)\n\nA = TypeVar('A', int, float, complex)\n\n\ndef derivada(p: Polinomio[A]) -> Polinomio[A]:\n    n = grado(p)\n    if n == 0:\n        return polCero()\n    b = coefLider(p)\n    r = restoPol(p)\n    return consPol(n - 1, b * n, derivada(r))\n\n# Propiedad. La derivada de la suma es la suma de las derivadas.\n@given(p=polinomioAleatorio(), q=polinomioAleatorio())\ndef test_derivada(p: Polinomio[int], q: Polinomio[int]) -> None:\n    assert derivada(sumaPol(p, q)) == sumaPol(derivada(p), derivada(q))\n\n# La comprobaci\u00f3n es\n#    > poetry run pytest -q Pol_Derivada_de_un_polinomio.py\n#    1 passed in 0.46s\n<\/pre>\n<p><a name=\"ej3\"><\/a><\/p>\n<h3>3. Resta de polinomios<\/h3>\n<p>Usando el <a href=\"https:\/\/bit.ly\/3KwqXYu\">tipo abstracto de los polinomios<\/a>, definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   restaPol :: (Num a, Eq a) => Polinomio a -> Polinomio a -> Polinomio a\n<\/pre>\n<p>tal que <code>restaPol p q<\/code> es el polinomio obtenido rest\u00e1ndole a <code>p<\/code> el <code>q<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> ejPol1 = consPol 5 1 (consPol 4 5 (consPol 2 5 (consPol 0 9 polCero)))\n   \u03bb> ejPol2 = consPol 4 3 (consPol 2 5 (consPol 0 3 polCero))\n   \u03bb> ejPol1\n   x^5 + 5*x^4 + 5*x^2 + 9\n   \u03bb> ejPol2\n   3*x^4 + 5*x^2 + 3\n   \u03bb> restaPol ejPol1 ejPol2\n   x^5 + 2*x^4 + 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.Polinomio (Polinomio, polCero, consPol)\nimport Pol_Suma_de_polinomios (sumaPol)\nimport Pol_Crea_termino (creaTermino)\nimport Pol_Producto_polinomios (multPorTerm)\n\nrestaPol :: (Num a, Eq a) => Polinomio a -> Polinomio a -> Polinomio a\nrestaPol p q  =\n  sumaPol p (multPorTerm (creaTermino 0 (-1)) q)\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom typing import TypeVar\n\nfrom src.Pol_Crea_termino import creaTermino\nfrom src.Pol_Producto_polinomios import multPorTerm\nfrom src.Pol_Suma_de_polinomios import sumaPol\nfrom src.TAD.Polinomio import Polinomio, consPol, polCero\n\nA = TypeVar('A', int, float, complex)\n\ndef restaPol(p: Polinomio[A], q: Polinomio[A]) -> Polinomio[A]:\n    return sumaPol(p, multPorTerm(creaTermino(0, -1), q))\n<\/pre>\n<p><a name=\"ej4\"><\/a><\/p>\n<h3>4. Potencia de un polinomio<\/h3>\n<p>Usando el <a href=\"https:\/\/bit.ly\/3KwqXYu\">tipo abstracto de los polinomios<\/a>, definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   potencia :: (Num a, Eq a) => Polinomio a -> Int -> Polinomio a\n<\/pre>\n<p>tal que <code>potencia p n<\/code> es la potencia <code>n<\/code>-\u00e9sima del polinomio <code>p<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> ejPol = consPol 1 2 (consPol 0 3 polCero)\n   \u03bb> ejPol\n   2*x + 3\n   \u03bb> potencia ejPol 2\n   4*x^2 + 12*x + 9\n   \u03bb> potencia ejPol 3\n   8*x^3 + 36*x^2 + 54*x + 27\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.Polinomio (Polinomio, polCero, consPol)\nimport Pol_Producto_polinomios (multPol)\nimport Test.QuickCheck\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\npotencia :: (Num a, Eq a) => Polinomio a -> Int -> Polinomio a\npotencia _ 0 = polUnidad\npotencia p n = multPol p (potencia p (n-1))\n\npolUnidad :: (Num a, Eq a) => Polinomio a\npolUnidad = consPol 0 1 polCero\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\npotencia2 :: (Num a, Eq a) => Polinomio a -> Int -> Polinomio a\npotencia2 _ 0 = polUnidad\npotencia2 p n\n  | even n    = potencia2 (multPol p p) (n `div` 2)\n  | otherwise = multPol p (potencia2 (multPol p p) ((n-1) `div` 2))\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_potencia :: Polinomio Int -> NonNegative Int -> Bool\nprop_potencia p (NonNegative n) =\n  potencia p n == potencia2 p n\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_potencia\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> import TAD.Polinomio (grado)\n--    \u03bb> ejPol = consPol 1 2 (consPol 0 3 polCero)\n--    \u03bb> grado (potencia ejPol 1000)\n--    1000\n--    (4.57 secs, 2,409,900,720 bytes)\n--    \u03bb> grado (potencia2 ejPol 1000)\n--    1000\n--    (2.78 secs, 1,439,596,632 bytes)\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom sys import setrecursionlimit\nfrom timeit import Timer, default_timer\nfrom typing import TypeVar\n\nfrom hypothesis import given\nfrom hypothesis import strategies as st\n\nfrom src.Pol_Producto_polinomios import multPol\nfrom src.TAD.Polinomio import Polinomio, consPol, polCero, polinomioAleatorio\n\nsetrecursionlimit(10**6)\n\nA = TypeVar('A', int, float, complex)\n\n# 1\u00aa soluci\u00f3n\n# ===========\n\ndef potencia(p: Polinomio[A], n: int) -> Polinomio[A]:\n    if n == 0:\n        return consPol(0, 1, polCero())\n    return multPol(p, potencia(p, n - 1))\n\n# 2\u00aa soluci\u00f3n\n# ===========\n\ndef potencia2(p: Polinomio[A], n: int) -> Polinomio[A]:\n    if n == 0:\n        return consPol(0, 1, polCero())\n    if n % 2 == 0:\n        return potencia2(multPol(p, p), n \/\/ 2)\n    return multPol(p, potencia2(multPol(p, p), (n - 1) \/\/ 2))\n\n# 3\u00aa soluci\u00f3n\n# ===========\n\ndef potencia3(p: Polinomio[A], n: int) -> Polinomio[A]:\n    r: Polinomio[A] = consPol(0, 1, polCero())\n    for _ in range(0, n):\n        r = multPol(p, r)\n    return r\n\n# Comprobaci\u00f3n de equivalencia\n# ============================\n\n# La propiedad es\n@given(p=polinomioAleatorio(),\n       n=st.integers(min_value=1, max_value=10))\ndef test_potencia(p: Polinomio[int], n: int) -> None:\n    r = potencia(p, n)\n    assert potencia2(p, n) == r\n    assert potencia3(p, n) == r\n\n# La comprobaci\u00f3n es\n#    src> poetry run pytest -q Pol_Potencia_de_un_polinomio.py\n#    1 passed in 0.89s\n\n# Comparaci\u00f3n de eficiencia\n# =========================\n\ndef tiempo(e: str) -> None:\n    \"\"\"Tiempo (en segundos) de evaluar la expresi\u00f3n e.\"\"\"\n    t = Timer(e, \"\", default_timer, globals()).timeit(1)\n    print(f\"{t:0.2f} segundos\")\n\n# La comparaci\u00f3n es\n#    >>> from src.TAD.Polinomio import grado\n#    >>> ejPol = consPol(1, 2, consPol(0, 3, polCero()))\n#    >>> tiempo('grado(potencia(ejPol, 1000))')\n#    8.58 segundos\n#    >>> tiempo('grado(potencia2(ejPol, 1000))')\n#    8.75 segundos\n<\/pre>\n<p><a name=\"ej5\"><\/a><\/p>\n<h3>5. Integral de un polinomio<\/h3>\n<p>Usando el <a href=\"https:\/\/bit.ly\/3KwqXYu\">tipo abstracto de los polinomios<\/a>, definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   integral :: (Fractional a, Eq a) => Polinomio a -> Polinomio a\n<\/pre>\n<p>tal que <code>integral p<\/code> es la integral del polinomio <code>p<\/code> cuyos coefientes son n\u00fameros racionales. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   \u03bb> ejPol = consPol 7 2 (consPol 4 5 (consPol 2 5 polCero))\n   \u03bb> ejPol\n   2*x^7 + 5*x^4 + 5*x^2\n   \u03bb> integral ejPol\n   0.25*x^8 + x^5 + 1.6666666666666667*x^3\n   \u03bb> integral ejPol :: Polinomio Rational\n   1 % 4*x^8 + x^5 + 5 % 3*x^3\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.Polinomio (Polinomio, polCero, consPol, esPolCero, grado,\n                      coefLider, restoPol)\nimport Data.Ratio\n\nintegral :: (Fractional a, Eq a) => Polinomio a -> Polinomio a\nintegral p\n  | esPolCero p = polCero\n  | otherwise   = consPol (n+1) (b \/ fromIntegral (n+1)) (integral r)\n  where n = grado p\n        b = coefLider p\n        r = restoPol p\n<\/pre>\n<p><a name=\"python\"><\/a><br \/>\n<b>Soluciones en Python<\/b><\/p>\n<pre lang=\"python\">\nfrom src.TAD.Polinomio import (Polinomio, coefLider, consPol, esPolCero, grado,\n                               polCero, restoPol)\n\n\ndef integral(p: Polinomio[float]) -> Polinomio[float]:\n    if esPolCero(p):\n        return  polCero()\n    n = grado(p)\n    b = coefLider(p)\n    r = restoPol(p)\n    return consPol(n + 1, b \/ (n + 1), integral(r))\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 los polinomios. 1. Comprobaci\u00f3n de ra\u00edces de polinomios 2. Derivada de un polinomio 3. Resta de polinomios 4. Potencia de un polinomio 5. Integral de un polinomio 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\/7932"}],"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=7932"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7932\/revisions"}],"predecessor-version":[{"id":7933,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/7932\/revisions\/7933"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=7932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=7932"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=7932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}