El tipo abstracto de datos de los polinomios
1. El tipo abstracto de datos de los polinomios
Un polinomio es una expresión matemática compuesta por una suma de términos, donde cada término es el producto de un coeficiente y una variable elevada a una potencia. Por ejemplo, el polinomio 3x^2+2x-1 tiene un término de segundo grado (3x^2), un término de primer grado (2x) y un término constante (-1).
Las operaciones que definen al tipo abstracto de datos (TAD) de los polinomios (cuyos coeficientes son del tipo a) son las siguientes:
1 2 3 4 5 6 |
polCero :: Polinomio a esPolCero :: Polinomio a -> Bool consPol :: (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a grado :: Polinomio a -> Int coefLider :: Num a => Polinomio a -> a restoPol :: (Num a, Eq a) => Polinomio a -> Polinomio a |
tales que
- polCero es el polinomio cero.
- (esPolCero p) se verifica si p es el polinomio cero.
- (consPol n b p) es el polinomio bx^n+p
- (grado p) es el grado del polinomio p.
- (coefLider p) es el coeficiente líder del polinomio p.
- (restoPol p) es el resto del polinomio p.
Por ejemplo, el polinomio
1 |
3*x^4 + -5*x^2 + 3 |
se representa por
1 |
consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero)) |
Las operaciones tienen que verificar las siguientes propiedades:
- esPolCero polCero
- n > grado p && b /= 0 ==> not (esPolCero (consPol n b p))
- consPol (grado p) (coefLider p) (restoPol p) == p
- n > grado p && b /= 0 ==> grado (consPol n b p) == n
- n > grado p && b /= 0 ==> coefLider (consPol n b p) == b
- n > grado p && b /= 0 ==> restoPol (consPol n b p) == p
2. Los polinomios en Haskell
2.1. El tipo abstracto de datos de los polinomios en Haskell
El TAD de los polinomios se encuentra en el módulo Polinomio.hs cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module TAD.Polinomio ( Polinomio, polCero, -- Polinomio a esPolCero, -- Polinomio a -> Bool consPol, -- (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a grado, -- Polinomio a -> Int coefLider, -- Num a => Polinomio a -> a restoPol -- (Num a, Eq a) => Polinomio a -> Polinomio a ) where import TAD.PolRepTDA -- import TAD.PolRepDensa -- import TAD.PolRepDispersa |
Para usar el TAD hay que usar una implementación concreta. En principio, consideraremos las siguientes:
- mediante tipo de dato algebraico,
- mediante listas densas y
- mediante listas dispersas.
Hay que elegir la que se desee utilizar, descomentándola y comentando las otras.
2.2. Implementación de los polinomios mediante tipos de datos algebraicos
Representamos un polinomio mediante los constructores ConsPol y
PolCero. Por ejemplo, el polinomio
1 |
6x^4 -5x^2 + 4x -7 |
se representa por
1 |
ConsPol 4 6 (ConsPol 2 (-5) (ConsPol 1 4 (ConsPol 0 (-7) PolCero))) |
La implementación se encuentra en el módulo PolRepTDA.hs cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module TAD.PolRepTDA ( Polinomio, polCero, -- Polinomio a esPolCero, -- Polinomio a -> Bool consPol, -- (Num a, Eq a)) => Int -> a -> Polinomio a -> Polinomio a grado, -- Polinomio a -> Int coefLider, -- Num t => Polinomio t -> t restoPol -- Polinomio t -> Polinomio t ) where import Test.QuickCheck -- Polinomio como tipo de dato algebra data Polinomio a = PolCero | ConsPol Int a (Polinomio a) deriving Eq -- (escribePol p) es la cadena correspondiente al polinomio p. Por -- ejemplo, -- λ> escribePol (consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))) -- "3*x^4 + -5*x^2 + 3" escribePol :: (Num a, Show a, Eq a) => Polinomio a -> String escribePol PolCero = "0" escribePol (ConsPol 0 b PolCero) = show b escribePol (ConsPol 0 b p) = concat [show b, " + ", escribePol p] escribePol (ConsPol 1 b PolCero) = show b ++ "*x" escribePol (ConsPol 1 b p) = concat [show b, "*x + ", escribePol p] escribePol (ConsPol n 1 PolCero) = "x^" ++ show n escribePol (ConsPol n b PolCero) = concat [show b, "*x^", show n] escribePol (ConsPol n 1 p) = concat ["x^", show n, " + ", escribePol p] escribePol (ConsPol n b p) = concat [show b, "*x^", show n, " + ", escribePol p] -- Procedimiento de escritura de polinomios. instance (Num a, Show a, Eq a) => Show (Polinomio a) where show = escribePol -- Ejemplos de polinomios con coeficientes enteros: ejPol1, ejPol2, ejPol3 :: Polinomio Int ejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero)) ejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero)) ejPol3 = consPol 4 6 (consPol 1 2 polCero) -- Comprobación de escritura: -- > ejPol1 -- 3*x^4 + -5*x^2 + 3 -- > ejPol2 -- x^5 + 5*x^2 + 4*x -- > ejPol3 -- 6*x^4 + 2*x -- polCero es el polinomio cero. Por ejemplo, -- > polCero -- 0 polCero :: Polinomio a polCero = PolCero -- (esPolCero p) se verifica si p es el polinomio cero. Por ejemplo, -- esPolCero polCero == True -- esPolCero ejPol1 == False esPolCero :: Polinomio a -> Bool esPolCero PolCero = True esPolCero _ = False -- (consPol n b p) es el polinomio bx^n+p. Por ejemplo, -- ejPol2 == x^5 + 5*x^2 + 4*x -- consPol 3 0 ejPol2 == x^5 + 5*x^2 + 4*x -- consPol 3 2 polCero == 2*x^3 -- consPol 6 7 ejPol2 == 7*x^6 + x^5 + 5*x^2 + 4*x -- consPol 4 7 ejPol2 == x^5 + 7*x^4 + 5*x^2 + 4*x -- consPol 5 7 ejPol2 == 8*x^5 + 5*x^2 + 4*x consPol :: (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a consPol _ 0 p = p consPol n b PolCero = ConsPol n b PolCero consPol n b (ConsPol m c p) | n > m = ConsPol n b (ConsPol m c p) | n < m = ConsPol m c (consPol n b p) | b+c == 0 = p | otherwise = ConsPol n (b+c) p -- (grado p) es el grado del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- grado ejPol3 == 4 grado :: Polinomio a -> Int grado PolCero = 0 grado (ConsPol n _ _) = n -- (coefLider p) es el coeficiente líder del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- coefLider ejPol3 == 6 coefLider :: Num t => Polinomio t -> t coefLider PolCero = 0 coefLider (ConsPol _ b _) = b -- (restoPol p) es el resto del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- restoPol ejPol3 == 2*x -- ejPol2 == x^5 + 5*x^2 + 4*x -- restoPol ejPol2 == 5*x^2 + 4*x restoPol :: Polinomio t -> Polinomio t restoPol PolCero = PolCero restoPol (ConsPol _ _ p) = p -- Generador de polinomios -- -- ======================= -- genPolinomio es un generador de polinomios. Por ejemplo, -- λ> sample (genPol 1) -- 7*x^9 + 9*x^8 + 10*x^7 + -14*x^5 + -15*x^2 + -10 -- -4*x^8 + 2*x -- -8*x^9 + 4*x^8 + 2*x^6 + 4*x^5 + -6*x^4 + 5*x^2 + -8*x -- -9*x^9 + x^5 + -7 -- 8*x^10 + -9*x^7 + 7*x^6 + 9*x^5 + 10*x^3 + -1*x^2 -- 7*x^10 + 5*x^9 + -5 -- -8*x^10 + -7 -- -5*x -- 5*x^10 + 4*x^4 + -3 -- 3*x^3 + -4 -- 10*x genPol :: (Num a, Arbitrary a, Eq a) => Int -> Gen (Polinomio a) genPol 0 = return polCero genPol _ = do n <- choose (0,10) b <- arbitrary p <- genPol (div n 2) return (consPol n b p) instance (Num a, Arbitrary a, Eq a) => Arbitrary (Polinomio a) where arbitrary = sized genPol -- Propiedades de los polinomios -- ============================= -- polCero es el polinomio cero. prop_polCero_es_cero :: Bool prop_polCero_es_cero = esPolCero polCero -- Si n es mayor que el grado de p y b no es cero, entonces -- (consPol n b p) es un polinomio distinto del cero. prop_consPol_no_cero :: Int -> Int -> Polinomio Int -> Property prop_consPol_no_cero n b p = n > grado p && b /= 0 ==> not (esPolCero (consPol n b p)) -- (consPol (grado p) (coefLider p) (restoPol p)) es igual a p. prop_consPol :: Polinomio Int -> Bool prop_consPol p = consPol (grado p) (coefLider p) (restoPol p) == p -- Si n es mayor que el grado de p y b no es cero, entonces -- el grado de (consPol n b p) es n. prop_grado :: Int -> Int -> Polinomio Int -> Property prop_grado n b p = n > grado p && b /= 0 ==> grado (consPol n b p) == n -- Si n es mayor que el grado de p y b no es cero, entonces -- el coeficiente líder de (consPol n b p) es b. prop_coefLider :: Int -> Int -> Polinomio Int -> Property prop_coefLider n b p = n > grado p && b /= 0 ==> coefLider (consPol n b p) == b -- Si n es mayor que el grado de p y b no es cero, entonces -- el resto de (consPol n b p) es p. prop_restoPol :: Int -> Int -> Polinomio Int -> Property prop_restoPol n b p = n > grado p && b /= 0 ==> restoPol (consPol n b p) == p -- Verificación -- ============ return [] verificaPol :: IO Bool verificaPol = $quickCheckAll -- La verificación es -- λ> verificaPol -- === prop_polCero_es_cero from PolPropiedades.hs:53 === -- +++ OK, passed 1 test. -- -- === prop_consPol_no_cero from PolPropiedades.hs:63 === -- +++ OK, passed 100 tests; 251 discarded. -- -- === prop_consPol from PolPropiedades.hs:73 === -- +++ OK, passed 100 tests. -- -- === prop_grado from PolPropiedades.hs:83 === -- +++ OK, passed 100 tests; 321 discarded. -- -- === prop_coefLider from PolPropiedades.hs:94 === -- +++ OK, passed 100 tests; 340 discarded. -- -- === prop_restoPol from PolPropiedades.hs:105 === -- +++ OK, passed 100 tests; 268 discarded. -- -- True |
2.3. Implementación de polinomios mediante listas densas
Representaremos un polinomio por la lista de sus coeficientes ordenados en orden decreciente según el grado. Por ejemplo, el polinomio
1 |
6x^4 -5x^2 + 4x -7 |
se representa por
1 |
[6,0,-2,4,-7] |
En la representación se supone que, si la lista no es vacía, su primer elemento es distinto de cero.
La implementación se encuentra en el módulo PolRepDensa.hs cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module TAD.PolRepDensa ( Polinomio, polCero, -- Polinomio a esPolCero, -- Polinomio a -> Bool consPol, -- (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a grado, -- Polinomio a -> Int coefLider, -- Num a => Polinomio a -> a restoPol -- (Num a, Eq a) => Polinomio a -> Polinomio a ) where import Test.QuickCheck newtype Polinomio a = Pol [a] deriving Eq -- (escribePol p) es la cadena correspondiente al polinomio p. Por -- ejemplo, -- λ> escribePol (consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))) -- "3*x^4 + -5*x^2 + 3" escribePol :: (Num a, Show a, Eq a) => Polinomio a -> String escribePol pol | esPolCero pol = "0" | n == 0 && esPolCero p = show a | n == 0 = concat [show a, " + ", escribePol p] | n == 1 && esPolCero p = show a ++ "*x" | n == 1 = concat [show a, "*x + ", escribePol p] | a == 1 && esPolCero p = "x^" ++ show n | esPolCero p = concat [show a, "*x^", show n] | a == 1 = concat ["x^", show n, " + ", escribePol p] | otherwise = concat [show a, "*x^", show n, " + ", escribePol p] where n = grado pol a = coefLider pol p = restoPol pol -- Procedimiento de escritura de polinomios. instance (Num a, Show a, Eq a) => Show (Polinomio a) where show = escribePol -- Ejemplos de polinomios con coeficientes enteros: ejPol1, ejPol2, ejPol3 :: Polinomio Int ejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero)) ejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero)) ejPol3 = consPol 4 6 (consPol 1 2 polCero) -- Comprobación de escritura: -- > ejPol1 -- 3*x^4 + -5*x^2 + 3 -- > ejPol2 -- x^5 + 5*x^2 + 4*x -- > ejPol3 -- 6*x^4 + 2*x -- polCero es el polinomio cero. Por ejemplo, -- λ> polCero -- 0 polCero :: Polinomio a polCero = Pol [] -- (esPolCero p) se verifica si p es el polinomio cero. Por ejemplo, -- esPolCero polCero == True -- esPolCero ejPol1 == False esPolCero :: Polinomio a -> Bool esPolCero (Pol []) = True esPolCero _ = False -- (consPol n b p) es el polinomio bx^n+p. Por ejemplo, -- ejPol2 == x^5 + 5*x^2 + 4*x -- consPol 3 0 ejPol2 == x^5 + 5*x^2 + 4*x -- consPol 3 2 polCero == 2*x^3 -- consPol 6 7 ejPol2 == 7*x^6 + x^5 + 5*x^2 + 4*x -- consPol 4 7 ejPol2 == x^5 + 7*x^4 + 5*x^2 + 4*x -- consPol 5 7 ejPol2 == 8*x^5 + 5*x^2 + 4*x consPol :: (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a consPol _ 0 p = p consPol n b p@(Pol xs) | esPolCero p = Pol (b : replicate n 0) | n > m = Pol (b : replicate (n-m-1) 0 ++ xs) | n < m = consPol m c (consPol n b (restoPol p)) | b+c == 0 = Pol (dropWhile (==0) (tail xs)) | otherwise = Pol ((b+c):tail xs) where c = coefLider p m = grado p -- (grado p) es el grado del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- grado ejPol3 == 4 grado :: Polinomio a -> Int grado (Pol []) = 0 grado (Pol xs) = length xs - 1 -- (coefLider p) es el coeficiente líder del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- coefLider ejPol3 == 6 coefLider :: Num t => Polinomio t -> t coefLider (Pol []) = 0 coefLider (Pol (a:_)) = a -- (restoPol p) es el resto del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- restoPol ejPol3 == 2*x -- ejPol2 == x^5 + 5*x^2 + 4*x -- restoPol ejPol2 == 5*x^2 + 4*x restoPol :: (Num t, Eq t) => Polinomio t -> Polinomio t restoPol (Pol []) = polCero restoPol (Pol [_]) = polCero restoPol (Pol (_:b:as)) | b == 0 = Pol (dropWhile (==0) as) | otherwise = Pol (b:as) -- Generador de polinomios -- ======================= -- genPolinomio es un generador de polinomios. Por ejemplo, -- λ> sample (genPol 1) -- 7*x^9 + 9*x^8 + 10*x^7 + -14*x^5 + -15*x^2 + -10 -- -4*x^8 + 2*x -- -8*x^9 + 4*x^8 + 2*x^6 + 4*x^5 + -6*x^4 + 5*x^2 + -8*x -- -9*x^9 + x^5 + -7 -- 8*x^10 + -9*x^7 + 7*x^6 + 9*x^5 + 10*x^3 + -1*x^2 -- 7*x^10 + 5*x^9 + -5 -- -8*x^10 + -7 -- -5*x -- 5*x^10 + 4*x^4 + -3 -- 3*x^3 + -4 -- 10*x genPol :: (Num a, Arbitrary a, Eq a) => Int -> Gen (Polinomio a) genPol 0 = return polCero genPol _ = do n <- choose (0,10) b <- arbitrary p <- genPol (div n 2) return (consPol n b p) instance (Num a, Arbitrary a, Eq a) => Arbitrary (Polinomio a) where arbitrary = sized genPol -- Propiedades de los polinomios -- ============================= -- polCero es el polinomio cero. prop_polCero_es_cero :: Bool prop_polCero_es_cero = esPolCero polCero -- Si n es mayor que el grado de p y b no es cero, entonces -- (consPol n b p) es un polinomio distinto del cero. prop_consPol_no_cero :: Int -> Int -> Polinomio Int -> Property prop_consPol_no_cero n b p = n > grado p && b /= 0 ==> not (esPolCero (consPol n b p)) -- (consPol (grado p) (coefLider p) (restoPol p)) es igual a p. prop_consPol :: Polinomio Int -> Bool prop_consPol p = consPol (grado p) (coefLider p) (restoPol p) == p -- Si n es mayor que el grado de p y b no es cero, entonces -- el grado de (consPol n b p) es n. prop_grado :: Int -> Int -> Polinomio Int -> Property prop_grado n b p = n > grado p && b /= 0 ==> grado (consPol n b p) == n -- Si n es mayor que el grado de p y b no es cero, entonces -- el coeficiente líder de (consPol n b p) es b. prop_coefLider :: Int -> Int -> Polinomio Int -> Property prop_coefLider n b p = n > grado p && b /= 0 ==> coefLider (consPol n b p) == b -- Si n es mayor que el grado de p y b no es cero, entonces -- el resto de (consPol n b p) es p. prop_restoPol :: Int -> Int -> Polinomio Int -> Property prop_restoPol n b p = n > grado p && b /= 0 ==> restoPol (consPol n b p) == p -- Verificación -- ============ return [] verificaPol :: IO Bool verificaPol = $quickCheckAll -- La verificación es -- λ> verificaPol -- === prop_polCero_es_cero from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDensa.hs:157 === -- +++ OK, passed 1 test. -- -- === prop_consPol_no_cero from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDensa.hs:163 === -- +++ OK, passed 100 tests; 274 discarded. -- -- === prop_consPol from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDensa.hs:169 === -- +++ OK, passed 100 tests. -- -- === prop_grado from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDensa.hs:175 === -- +++ OK, passed 100 tests; 297 discarded. -- -- === prop_coefLider from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDensa.hs:182 === -- +++ OK, passed 100 tests; 248 discarded. -- -- === prop_restoPol from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDensa.hs:189 === -- +++ OK, passed 100 tests; 322 discarded. -- -- True |
2.4. Implementación de polinomios mediante listas dispersas
Representaremos un polinomio mediante una lista de pares (grado,coef),
ordenados en orden decreciente según el grado. Por ejemplo, el polinomio
1 |
6x^4 -5x^2 + 4x -7 |
se representa por
1 |
[(4,6),(2,-5),(1,4),(0,-7)] |
En la representación se supone que los primeros elementos de los pares forman una sucesión estrictamente decreciente y que los segundos elementos son distintos de cero.
La implementación se encuentra en el módulo PolRepDispersa.hs cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
{-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fno-warn-unused-top-binds #-} module TAD.PolRepDispersa ( Polinomio, polCero, -- Polinomio a esPolCero, -- Num a => Polinomio a -> Bool consPol, -- Num a => Int -> a -> Polinomio a -> Polinomio a grado, -- Polinomio a -> Int coefLider, -- Num a => Polinomio a -> a restoPol -- Polinomio a -> Polinomio a ) where import Test.QuickCheck newtype Polinomio a = Pol [(Int,a)] deriving Eq -- (escribePol p) es la cadena correspondiente al polinomio p. Por -- ejemplo, -- λ> escribePol (consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))) -- "3*x^4 + -5*x^2 + 3" escribePol :: (Num a, Show a, Eq a) => Polinomio a -> String escribePol pol | esPolCero pol = "0" | n == 0 && esPolCero p = show a | n == 0 = concat [show a, " + ", escribePol p] | n == 1 && esPolCero p = show a ++ "*x" | n == 1 = concat [show a, "*x + ", escribePol p] | a == 1 && esPolCero p = "x^" ++ show n | esPolCero p = concat [show a, "*x^", show n] | a == 1 = concat ["x^", show n, " + ", escribePol p] | otherwise = concat [show a, "*x^", show n, " + ", escribePol p] where n = grado pol a = coefLider pol p = restoPol pol -- Procedimiento de escritura de polinomios. instance (Num a, Show a, Eq a) => Show (Polinomio a) where show = escribePol -- Ejemplos de polinomios con coeficientes enteros: ejPol1, ejPol2, ejPol3 :: Polinomio Int ejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero)) ejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero)) ejPol3 = consPol 4 6 (consPol 1 2 polCero) -- Comprobación de escritura: -- > ejPol1 -- 3*x^4 + -5*x^2 + 3 -- > ejPol2 -- x^5 + 5*x^2 + 4*x -- > ejPol3 -- 6*x^4 + 2*x -- polCero es el polinomio cero. Por ejemplo, -- λ> polCero -- 0 polCero :: Num a => Polinomio a polCero = Pol [] -- (esPolCero p) se verifica si p es el polinomio cero. Por ejemplo, -- esPolCero polCero == True -- esPolCero ejPol1 == False esPolCero :: Num a => Polinomio a -> Bool esPolCero (Pol []) = True esPolCero _ = False -- (consPol n b p) es el polinomio bx^n+p. Por ejemplo, -- ejPol2 == x^5 + 5*x^2 + 4*x -- consPol 3 0 ejPol2 == x^5 + 5*x^2 + 4*x -- consPol 3 2 polCero == 2*x^3 -- consPol 6 7 ejPol2 == 7*x^6 + x^5 + 5*x^2 + 4*x -- consPol 4 7 ejPol2 == x^5 + 7*x^4 + 5*x^2 + 4*x -- consPol 5 7 ejPol2 == 8*x^5 + 5*x^2 + 4*x consPol :: (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a consPol _ 0 p = p consPol n b p@(Pol xs) | esPolCero p = Pol [(n,b)] | n > m = Pol ((n,b):xs) | n < m = consPol m c (consPol n b (Pol (tail xs))) | b+c == 0 = Pol (tail xs) | otherwise = Pol ((n,b+c) : tail xs) where c = coefLider p m = grado p -- (grado p) es el grado del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- grado ejPol3 == 4 grado :: Polinomio a -> Int grado (Pol []) = 0 grado (Pol ((n,_):_)) = n -- (coefLider p) es el coeficiente líder del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- coefLider ejPol3 == 6 coefLider :: Num t => Polinomio t -> t coefLider (Pol []) = 0 coefLider (Pol ((_,b):_)) = b -- (restoPol p) es el resto del polinomio p. Por ejemplo, -- ejPol3 == 6*x^4 + 2*x -- restoPol ejPol3 == 2*x -- ejPol2 == x^5 + 5*x^2 + 4*x -- restoPol ejPol2 == 5*x^2 + 4*x restoPol :: Num t => Polinomio t -> Polinomio t restoPol (Pol []) = polCero restoPol (Pol [_]) = polCero restoPol (Pol (_:xs)) = Pol xs -- Generador de polinomios -- -- ======================= -- genPolinomio es un generador de polinomios. Por ejemplo, -- λ> sample (genPol 1) -- 7*x^9 + 9*x^8 + 10*x^7 + -14*x^5 + -15*x^2 + -10 -- -4*x^8 + 2*x -- -8*x^9 + 4*x^8 + 2*x^6 + 4*x^5 + -6*x^4 + 5*x^2 + -8*x -- -9*x^9 + x^5 + -7 -- 8*x^10 + -9*x^7 + 7*x^6 + 9*x^5 + 10*x^3 + -1*x^2 -- 7*x^10 + 5*x^9 + -5 -- -8*x^10 + -7 -- -5*x -- 5*x^10 + 4*x^4 + -3 -- 3*x^3 + -4 -- 10*x genPol :: (Num a, Arbitrary a, Eq a) => Int -> Gen (Polinomio a) genPol 0 = return polCero genPol _ = do n <- choose (0,10) b <- arbitrary p <- genPol (div n 2) return (consPol n b p) instance (Num a, Arbitrary a, Eq a) => Arbitrary (Polinomio a) where arbitrary = sized genPol -- Propiedades de los polinomios -- ============================= -- polCero es el polinomio cero. prop_polCero_es_cero :: Bool prop_polCero_es_cero = esPolCero polCero -- Si n es mayor que el grado de p y b no es cero, entonces -- (consPol n b p) es un polinomio distinto del cero. prop_consPol_no_cero :: Int -> Int -> Polinomio Int -> Property prop_consPol_no_cero n b p = n > grado p && b /= 0 ==> not (esPolCero (consPol n b p)) -- (consPol (grado p) (coefLider p) (restoPol p)) es igual a p. prop_consPol :: Polinomio Int -> Bool prop_consPol p = consPol (grado p) (coefLider p) (restoPol p) == p -- Si n es mayor que el grado de p y b no es cero, entonces -- el grado de (consPol n b p) es n. prop_grado :: Int -> Int -> Polinomio Int -> Property prop_grado n b p = n > grado p && b /= 0 ==> grado (consPol n b p) == n -- Si n es mayor que el grado de p y b no es cero, entonces -- el coeficiente líder de (consPol n b p) es b. prop_coefLider :: Int -> Int -> Polinomio Int -> Property prop_coefLider n b p = n > grado p && b /= 0 ==> coefLider (consPol n b p) == b -- Si n es mayor que el grado de p y b no es cero, entonces -- el resto de (consPol n b p) es p. prop_restoPol :: Int -> Int -> Polinomio Int -> Property prop_restoPol n b p = n > grado p && b /= 0 ==> restoPol (consPol n b p) == p -- Verificación -- ============ return [] verificaPol :: IO Bool verificaPol = $quickCheckAll -- La verificación es -- λ> verificaPol -- === prop_polCero_es_cero from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDispersa.hs:156 === -- +++ OK, passed 1 test. -- -- === prop_consPol_no_cero from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDispersa.hs:162 === -- +++ OK, passed 100 tests; 264 discarded. -- -- === prop_consPol from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDispersa.hs:168 === -- +++ OK, passed 100 tests. -- -- === prop_grado from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDispersa.hs:174 === -- +++ OK, passed 100 tests; 266 discarded. -- -- === prop_coefLider from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDispersa.hs:181 === -- +++ OK, passed 100 tests; 251 discarded. -- -- === prop_restoPol from /home/jalonso/alonso/estudio/Exercitium/Exercitium/src/TAD/PolRepDispersa.hs:188 === -- +++ OK, passed 100 tests; 254 discarded. -- -- True |
3. Los polinomios en Python
3.1. El tipo abstracto de los polinomios en Python
La implementación se encuentra en el módulo Polinomio.py cuyo contenido es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
__all__ = [ 'Polinomio', 'polCero', 'esPolCero', 'consPol', 'grado', 'coefLider', 'restoPol', 'polinomioAleatorio' ] from src.TAD.PolRepDensa import (Polinomio, coefLider, consPol, esPolCero, grado, polCero, polinomioAleatorio, restoPol) # from src.TAD.PolRepDispersa import (Polinomio, polCero, esPolCero, # consPol, grado, coefLider, # restoPol, polinomioAleatorio) |
Para usar el TAD hay que usar una implementación concreta. En principio, consideraremos las siguientes:
- mediante listas densas y
- mediante listas dispersas.
3.2. Implementación de los polinomios mediante listas densas
Representaremos un polinomio por la lista de sus coeficientes ordenados en orden decreciente según el grado. Por ejemplo, el polinomio
1 |
6x^4 -5x^2 + 4x -7 |
se representa por
1 |
[6,0,-2,4,-7] |
En la representación se supone que, si la lista no es vacía, su primer elemento es distinto de cero.
Se define la clase Polinomio con los siguientes métodos:
- esPolCero() se verifica si es el polinomio cero.
- consPol(n, b) es el polinomio obtenido añadiendo el térmiono bx^n
- grado() es el grado del polinomio.
- coefLider() es el coeficiente líder del polinomio.
- restoPol() es el resto del polinomio.
Por ejemplo,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
>>> Polinomio() 0 >>> ejPol1 = Polinomio().consPol(0,3).consPol(2,-5).consPol(4,3) >>> ejPol1 3*x^4 + -5*x^2 + 3 >>> ejPol2 = Polinomio().consPol(1,4).consPol(2,5).consPol(5,1) >>> ejPol2 x^5 + 5*x^2 + 4*x >>> ejPol3 = Polinomio().consPol(1,2).consPol(4,6) >>> ejPol3 6*x^4 + 2*x >>> Polinomio().esPolCero() True >>> ejPol1.esPolCero() False >>> ejPol2 x^5 + 5*x^2 + 4*x >>> ejPol2.consPol(3,0) x^5 + 5*x^2 + 4*x >>> Polinomio().consPol(3,2) 2*x^3 >>> ejPol2.consPol(6,7) 7*x^6 + x^5 + 5*x^2 + 4*x >>> ejPol2.consPol(4,7) x^5 + 7*x^4 + 5*x^2 + 4*x >>> ejPol2.consPol(5,7) 8*x^5 + 5*x^2 + 4*x >>> ejPol3 6*x^4 + 2*x >>> ejPol3.grado() 4 >>> ejPol3.restoPol() 2*x >>> ejPol2 x^5 + 5*x^2 + 4*x >>> ejPol2.restoPol() 5*x^2 + 4*x |
Además se definen las correspondientes funciones. Por ejemplo,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
>>> polCero() 0 >>> ejPol1a = consPol(4,3,consPol(2,-5,consPol(0,3,polCero()))) >>> ejPol1a 3*x^4 + -5*x^2 + 3 >>> ejPol2a = consPol(5,1,consPol(2,5,consPol(1,4,polCero()))) >>> ejPol2a x^5 + 5*x^2 + 4*x >>> ejPol3a = consPol(4,6,consPol(1,2,polCero())) >>> ejPol3a 6*x^4 + 2*x >>> esPolCero(polCero()) True >>> esPolCero(ejPol1a) False >>> ejPol2a x^5 + 5*x^2 + 4*x >>> consPol(3,9,ejPol2a) x^5 + 9*x^3 + 5*x^2 + 4*x >>> consPol(3,2,polCero()) 2*x^3 >>> consPol(6,7,ejPol2a) 7*x^6 + x^5 + 5*x^2 + 4*x >>> consPol(4,7,ejPol2a) x^5 + 7*x^4 + 5*x^2 + 4*x >>> consPol(5,7,ejPol2a) 8*x^5 + 5*x^2 + 4*x >>> ejPol3a 6*x^4 + 2*x >>> grado(ejPol3a) 4 >>> restoPol(ejPol3a) 2*x >>> ejPol2a x^5 + 5*x^2 + 4*x >>> restoPol(ejPol2a) 5*x^2 + 4*x |
Finalmente, se define un generador aleatorio de polinomios y se comprueba que los polinomios cumplen las propiedades de su especificación.
La implementación se encuentra en el módulo PolRepDensa.py en el que se define la clase Conj con los siguientes métodos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
from __future__ import annotations __all__ = [ 'Polinomio', 'polCero', 'esPolCero', 'consPol', 'grado', 'coefLider', 'restoPol', 'polinomioAleatorio' ] from dataclasses import dataclass, field from itertools import dropwhile from typing import Generic, TypeVar from hypothesis import assume, given from hypothesis import strategies as st A = TypeVar('A', int, float, complex) # Clase de los polinomios mediante listas densas # ============================================== @dataclass class Polinomio(Generic[A]): _coeficientes: list[A] = field(default_factory=list) def esPolCero(self) -> bool: return not self._coeficientes def grado(self) -> int: if self.esPolCero(): return 0 return len(self._coeficientes) - 1 def coefLider(self) -> A: if self.esPolCero(): return 0 return self._coeficientes[0] def restoPol(self) -> Polinomio[A]: xs = self._coeficientes if len(xs) <= 1: return Polinomio([]) if xs[1] == 0: return Polinomio(list(dropwhile(lambda x: x == 0, xs[2:]))) return Polinomio(xs[1:]) def consPol(self, n: int, b: A) -> Polinomio[A]: m = self.grado() c = self.coefLider() xs = self._coeficientes if b == 0: return self if self.esPolCero(): return Polinomio([b] + ([0] * n)) if n > m: return Polinomio([b] + ([0] * (n-m-1)) + xs) if n < m: return self.restoPol().consPol(n, b).consPol(m, c) if b + c == 0: return Polinomio(list(dropwhile(lambda x: x == 0, xs[1:]))) return Polinomio([b + c] + xs[1:]) def __repr__(self) -> str: n = self.grado() a = self.coefLider() p = self.restoPol() if self.esPolCero(): return "0" if n == 0 and p.esPolCero(): return str(a) if n == 0: return str(a) + " + " + str(p) if n == 1 and p.esPolCero(): return str(a) + "*x" if n == 1: return str(a) + "*x + " + str(p) if a == 1 and p.esPolCero(): return "x^" + str(n) if p.esPolCero(): return str(a) + "*x^" + str(n) if a == 1: return "x^" + str(n) + " + " + str(p) return str(a) + "*x^" + str(n) + " + " + str(p) # Funciones del tipo polinomio # ============================ def polCero() -> Polinomio[A]: return Polinomio([]) def esPolCero(p: Polinomio[A]) -> bool: return p.esPolCero() def grado(p: Polinomio[A]) -> int: return p.grado() def coefLider(p: Polinomio[A]) -> A: return p.coefLider() def restoPol(p: Polinomio[A]) -> Polinomio[A]: return p.restoPol() def consPol(n: int, b: A, p: Polinomio[A]) -> Polinomio[A]: return p.consPol(n, b) # Generador de polinomios # ======================= # normal(xs) es la lista obtenida eliminando los ceros iniciales de # xs. Por ejmplo, # >>> normal([0,0,5,0]) # [5, 0] # >>> normal([0,0,0,0]) # [] def normal(xs: list[A]) -> list[A]: return list(dropwhile(lambda x: x == 0, xs)) # polinomioAleatorio() genera polinomios aleatorios. Por ejemplo, # >>> polinomioAleatorio().example() # 9*x^6 + -7*x^5 + 7*x^3 + x^2 + 7 # >>> polinomioAleatorio().example() # -3*x^7 + 8*x^6 + 2*x^5 + x^4 + -1*x^3 + -6*x^2 + 8*x + -6 # >>> polinomioAleatorio().example() # x^2 + 7*x + -1 def polinomioAleatorio() -> st.SearchStrategy[Polinomio[int]]: return st.lists(st.integers(min_value=-9, max_value=9), max_size=10)\ .map(lambda xs: normal(xs))\ .map(Polinomio) # Comprobación de las propiedades de los polinomios # ================================================= # Las propiedades son def test_esPolCero1() -> None: assert esPolCero(polCero()) @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_esPolCero2(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert not esPolCero(consPol(n, b, p)) @given(p=polinomioAleatorio()) def test_consPol(p: Polinomio[int]) -> None: assume(not esPolCero(p)) assert consPol(grado(p), coefLider(p), restoPol(p)) == p @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_grado(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert grado(consPol(n, b, p)) == n @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_coefLider(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert coefLider(consPol(n, b, p)) == b @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_restoPol(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert restoPol(consPol(n, b, p)) == p # La comprobación es # > poetry run pytest -v PolRepDensa.py # # PolRepDensa.py::test_esPolCero1 PASSED # PolRepDensa.py::test_esPolCero2 PASSED # PolRepDensa.py::test_consPol PASSED # PolRepDensa.py::test_grado PASSED # PolRepDensa.py::test_coefLider PASSED # PolRepDensa.py::test_restoPol PASSED # # === 6 passed in 1.64s === |
3.3. Implementación de los polinomios mediante listas dispersas
Representaremos un polinomio mediante una lista de pares (grado,coef), ordenados en orden decreciente según el grado. Por ejemplo, el polinomio
1 |
6x^4 -5x^2 + 4x -7 |
se representa por
1 |
[(4,6),(2,-5),(1,4),(0,-7)] |
En la representación se supone que los primeros elementos de los pares forman una sucesión estrictamente decreciente y que los segundos elementos son distintos de cero.
La implementación se encuentra en el módulo PolRepDispersa.py cuyo contenido es
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
from __future__ import annotations __all__ = [ 'Polinomio', 'polCero', 'esPolCero', 'consPol', 'grado', 'coefLider', 'restoPol', 'polinomioAleatorio' ] from dataclasses import dataclass, field from typing import Generic, TypeVar from hypothesis import assume, given from hypothesis import strategies as st A = TypeVar('A', int, float, complex) # Clase de los polinomios mediante listas densas # ============================================== @dataclass class Polinomio(Generic[A]): _terminos: list[tuple[int, A]] = field(default_factory=list) def esPolCero(self) -> bool: return not self._terminos def grado(self) -> int: if self.esPolCero(): return 0 return self._terminos[0][0] def coefLider(self) -> A: if self.esPolCero(): return 0 return self._terminos[0][1] def restoPol(self) -> Polinomio[A]: xs = self._terminos if len(xs) <= 1: return Polinomio([]) return Polinomio(xs[1:]) def consPol(self, n: int, b: A) -> Polinomio[A]: m = self.grado() c = self.coefLider() xs = self._terminos if b == 0: return self if self.esPolCero(): return Polinomio([(n, b)]) if n > m: return Polinomio([(n, b)] + xs) if n < m: return Polinomio(xs[1:]).consPol(n, b).consPol(m, c) if b + c == 0: return Polinomio(xs[1:]) return Polinomio([(n, b + c)] + xs[1:]) def __repr__(self) -> str: n = self.grado() a = self.coefLider() p = self.restoPol() if self.esPolCero(): return "0" if n == 0 and p.esPolCero(): return str(a) if n == 0: return str(a) + " + " + str(p) if n == 1 and p.esPolCero(): return str(a) + "*x" if n == 1: return str(a) + "*x + " + str(p) if a == 1 and p.esPolCero(): return "x^" + str(n) if p.esPolCero(): return str(a) + "*x^" + str(n) if a == 1: return "x^" + str(n) + " + " + str(p) return str(a) + "*x^" + str(n) + " + " + str(p) # Funciones del tipo polinomio # ============================ def polCero() -> Polinomio[A]: return Polinomio([]) def esPolCero(p: Polinomio[A]) -> bool: return p.esPolCero() def grado(p: Polinomio[A]) -> int: return p.grado() def coefLider(p: Polinomio[A]) -> A: return p.coefLider() def restoPol(p: Polinomio[A]) -> Polinomio[A]: return p.restoPol() def consPol(n: int, b: A, p: Polinomio[A]) -> Polinomio[A]: return p.consPol(n, b) # Generador de polinomios # ======================= # normal(ps) es la representación dispersa de un polinomio. def normal(ps: list[tuple[int, A]]) -> list[tuple[int, A]]: xs = sorted(list({p[0] for p in ps}), reverse=True) ys = [p[1] for p in ps] return [(x, y) for (x, y) in zip(xs, ys) if y != 0] # polinomioAleatorio() genera polinomios aleatorios. Por ejemplo, # >>> polinomioAleatorio().example() # -4*x^8 + -5*x^7 + -4*x^6 + -4*x^5 + -8*x^3 # >>> polinomioAleatorio().example() # -7*x^9 + -8*x^6 + -8*x^3 + 2*x^2 + -1*x + 4 def polinomioAleatorio() -> st.SearchStrategy[Polinomio[int]]: return st.lists(st.tuples(st.integers(min_value=0, max_value=9), st.integers(min_value=-9, max_value=9)))\ .map(lambda ps: normal(ps))\ .map(Polinomio) # Comprobación de las propiedades de los polinomios # ================================================= # Las propiedades son def test_esPolCero1() -> None: assert esPolCero(polCero()) @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_esPolCero2(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert not esPolCero(consPol(n, b, p)) @given(p=polinomioAleatorio()) def test_consPol(p: Polinomio[int]) -> None: assume(not esPolCero(p)) assert consPol(grado(p), coefLider(p), restoPol(p)) == p @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_grado(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert grado(consPol(n, b, p)) == n @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_coefLider(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert coefLider(consPol(n, b, p)) == b @given(p=polinomioAleatorio(), n=st.integers(min_value=0, max_value=10), b=st.integers()) def test_restoPol(p: Polinomio[int], n: int, b: int) -> None: assume(n > grado(p) and b != 0) assert restoPol(consPol(n, b, p)) == p # La comprobación es # > poetry run pytest -v PolRepDispersa.py # # PolRepDispersa.py::test_esPolCero1 PASSED # PolRepDispersa.py::test_esPolCero2 PASSED # PolRepDispersa.py::test_consPol PASSED # PolRepDispersa.py::test_grado PASSED # PolRepDispersa.py::test_coefLider PASSED # PolRepDispersa.py::test_restoPol PASSED # # === 6 passed in 1.74s === |