Advertisement
lucks232

Untitled

Dec 29th, 2023
1,130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.72 KB | None | 0 0
  1. # creación de la clase polinomio
  2. class Polinomio:
  3.     def __init__(self, coeficientes):
  4.         self.coeficientes = coeficientes
  5.  
  6.     # constructor del polinomio
  7.     def __str__(self):
  8.         # podríamos haber definido el polinomio como una cadena vacía también
  9.         terminos = []
  10.  
  11.         # al usar enumerate podemos asignar 2 variables al bucle for (i -> posición), (coef -> el coeficiente) en lugar de usar una variable auxiliar de contador
  12.         for i, coef in enumerate(self.coeficientes):
  13.             if coef == 0:
  14.                 # al contrario de break, continue, nos hace saltar directamente a la siguiente iteración del for
  15.                 continue
  16.             potencia = (len(self.coeficientes)-1) - i
  17.             # condiciones
  18.             if potencia == 0:
  19.                 terminos.append(f"{coef}")
  20.             elif potencia == 1:
  21.                 if coef == 1:
  22.                     terminos.append("x")
  23.                 elif coef == -1:
  24.                     terminos.append("-x")
  25.                 else:
  26.                     terminos.append(f"{coef}x")
  27.             else:
  28.                 if coef == 1:
  29.                     terminos.append(f"x^{potencia}")
  30.                 elif coef == -1:
  31.                     terminos.append(f"-x^{potencia}")
  32.                 else:
  33.                     terminos.append(f"{coef}x^{potencia}")
  34.         #unimos terminos de la lista con + y reemplazamos "+ -" por "- " en caso de que los coeficientes sean negativos
  35.         polinomio = ' + '.join(terminos).replace("+ -","- ")
  36.  
  37.         if not terminos:
  38.             return "0"
  39.        
  40.         return polinomio
  41.    
  42.     def evaluar(self, x):
  43.         coeficientes = self.coeficientes  # se obtienen los coeficientes del polinomio
  44.         imagen = 0
  45.  
  46.         # se recorre la lista de coeficientes para calcular el valor del polinomio
  47.         for i, coef in enumerate(coeficientes):
  48.             # se calcula el término correspondiente y se suma a la imagen
  49.             if (len(coeficientes)-1-i) != 0:
  50.                 imagen += pow(x, len(coeficientes)-1-i) * coef
  51.             else:
  52.                 # cuando es el término independiente (potencia 0), se suma directamente el coeficiente
  53.                 imagen += coef
  54.         return imagen
  55.    
  56.     def mul_real(self, x):
  57.         coeficientes_copia = []
  58.         # copiamos el polinomio original a una copia para no modificarlo
  59.         for coef in self.coeficientes:
  60.             coeficientes_copia.append(coef)
  61.  
  62.         # se multiplica cada coeficiente por el número real 'x'
  63.         for i, coef in enumerate(coeficientes_copia):
  64.             coeficientes_copia[i] = coef*x  # actualiza el coeficiente multiplicándolo por x
  65.        
  66.         return Polinomio(coeficientes_copia)
  67.        
  68.     def pol_opuesto(self):
  69.         coeficientes_copia = []
  70.         # hacemos la copia
  71.         for coef in self.coeficientes:
  72.             coeficientes_copia.append(coef)
  73.  
  74.         # se cambia el signo de cada coeficiente para obtener el polinomio opuesto
  75.         for i, coef in enumerate(coeficientes_copia):
  76.             coeficientes_copia[i] = coef*(-1)  # cambia el signo del coeficiente
  77.        
  78.         return Polinomio(coeficientes_copia)  # devuelve el polinomio opuesto
  79.        
  80.     def derivada(self):
  81.         # crear una copia de la lista de coeficientes para manipularla
  82.         coeficientes_copia = []
  83.         for coef in self.coeficientes:
  84.             coeficientes_copia.append(coef)
  85.        
  86.         # eliminar el término constante ya que su derivada es 0
  87.         coeficientes_copia.pop()
  88.        
  89.         # lista para almacenar los coeficientes derivados
  90.         coeficientes_derivados = []
  91.  
  92.         # calcular la derivada de cada término del polinomio
  93.         for i, coef in enumerate(coeficientes_copia):
  94.             grado = len(coeficientes_copia)-i  # determinar el grado del término
  95.             coef = coef*grado
  96.             coeficientes_derivados.append(coef)
  97.        
  98.         # devolver un nuevo polinomio con los coeficientes derivados
  99.         return Polinomio(coeficientes_derivados)
  100.    
  101.     def suma_pol(self, other):
  102.         # invertir las listas de coeficientes para trabajar de menor a mayor grado
  103.         polinomio1 = list(reversed(self.coeficientes))
  104.         polinomio2 = list(reversed(other.coeficientes))
  105.  
  106.         max_longitud = max(len(polinomio1), len(polinomio2))
  107.         polinomio1_l = polinomio1 + (max_longitud - len(polinomio1))*[0]
  108.         polinomio2_l = polinomio2 + (max_longitud - len(polinomio2))*[0]
  109.  
  110.         # sumar los coeficientes correspondientes de los dos polinomios
  111.         coeficientes_suma = []
  112.         for i in range(max_longitud):
  113.             coeficientes_suma.append(polinomio1_l[i] + polinomio2_l[i])
  114.  
  115.         # invertir de nuevo para obtener el orden correcto de coeficientes
  116.         coeficientes_suma = list(reversed(coeficientes_suma))
  117.        
  118.         return Polinomio(coeficientes_suma)
  119.  
  120.     def resta_pol(self, other):
  121.         polinomio1 = list(reversed(self.coeficientes))
  122.         polinomio2 = list(reversed(other.coeficientes))
  123.  
  124.         max_longitud = max(len(polinomio1), len(polinomio2))
  125.         polinomio1_l = polinomio1 + (max_longitud - len(polinomio1))*[0]
  126.         polinomio2_l = polinomio2 + (max_longitud - len(polinomio2))*[0]
  127.  
  128.         # restar los coeficientes correspondientes
  129.         coeficientes_resta = []
  130.         for i in range(max_longitud):
  131.             coeficientes_resta.append(polinomio1_l[i] - polinomio2_l[i])
  132.  
  133.         coeficientes_resta = list(reversed(coeficientes_resta))
  134.        
  135.         return Polinomio(coeficientes_resta)
  136.    
  137.     def mul_pol(self, other):
  138.         polinomio1 = list(reversed(self.coeficientes))
  139.         polinomio2 = list(reversed(other.coeficientes))
  140.  
  141.         # se inicializa el resultado con ceros para almacenar los coeficientes resultantes
  142.         resultado = [0] * (len(polinomio1) + len(polinomio2) - 1)
  143.         for i, coef1 in enumerate(polinomio1):
  144.             for j, coef2 in enumerate(polinomio2):
  145.                 resultado[i+j] += coef1 * coef2
  146.        
  147.         # eliminar ceros al final que no representan términos
  148.         while len(resultado) > 1 and resultado[-1] == 0:
  149.             resultado.pop()
  150.        
  151.         # devolver nuevo polinomio con coeficientes invertidos a su orden original
  152.         return Polinomio(list(reversed(resultado)))
  153.  
  154.     def div_pol(self, other):
  155.         polinomio1 = list(reversed(self.coeficientes))
  156.         polinomio2 = list(reversed(other.coeficientes))
  157.  
  158.         # determinar grados de los polinomios para guiar la división
  159.         grado_dividendo = len(polinomio1) - 1
  160.         grado_divisor = len(polinomio2) - 1
  161.  
  162.         # inicializar cociente con ceros
  163.         cociente = [0] * max(1, grado_dividendo - grado_divisor + 1)
  164.         while grado_dividendo >= grado_divisor and grado_dividendo >= 0:
  165.             # calcular factor del término actual del cociente
  166.             factor = polinomio1[grado_dividendo] / polinomio2[grado_divisor]
  167.             cociente[grado_dividendo - grado_divisor] = factor
  168.  
  169.             # restar el múltiplo del divisor del dividendo
  170.             for i in range(len(polinomio2)):
  171.                 if grado_dividendo - i < 0:
  172.                     break
  173.                 polinomio1[grado_dividendo - i] -= polinomio2[grado_divisor - i] * factor
  174.  
  175.             # ajustar grado del dividendo después de la substracción
  176.             while grado_dividendo >= 0 and (grado_dividendo >= len(polinomio1) or polinomio1[grado_dividendo] == 0):
  177.                 grado_dividendo -= 1
  178.  
  179.         # recolectar y ajustar los términos restantes como el resto
  180.         resto = list(reversed(polinomio1[:max(0, grado_dividendo + 1)]))
  181.  
  182.         # convertimos los coeficientes a enteros si son enteros exactos para limpieza de n.0
  183.         for i, coef in enumerate(resto):
  184.             if resto[i] % 1 == 0:
  185.                 resto[i] = int(resto[i])
  186.        
  187.         for i, coef in enumerate(cociente):
  188.             if coef % 1 == 0:
  189.                 cociente[i] = int(cociente[i])
  190.  
  191.         # se eliminan ceros innecesarios del cociente
  192.         while len(cociente) > 1 and cociente[-1] == 0:
  193.             cociente.pop()
  194.  
  195.         return Polinomio(list(reversed(cociente))), Polinomio(resto)
  196.  
  197.     # Los método de aquí en adelante han sido estructurados para ser usados dentro del método factorizar()
  198.     # El razonamiento que se ha hecho para poder por lo menos factorizar polinomios con soluciones racionales ha sido
  199.     # 1) MCD -> Simplificamos -> Ruffini -> Iteramos
  200.     def mcd(self):
  201.         # definición de la función euclides para calcular el mcd de dos números
  202.         def euclides(a, b):
  203.             # bucle mientras b sea diferente de cero
  204.             while b != 0:
  205.                 # actualizamos los valores de a y b usando el algoritmo de euclides
  206.                 a, b = b, a % b
  207.             return a
  208.        
  209.         # inicializamos mcd con el primer coeficiente del polinomio
  210.         mcd = self.coeficientes[0]
  211.         # iteramos sobre los coeficientes del polinomio
  212.         for coef in self.coeficientes[1:]:
  213.             # actualizamos el mcd con el mcd del coeficiente actual y el mcd acumulado
  214.             mcd = euclides(mcd, coef)
  215.         return mcd
  216.    
  217.     def simplificar(self):
  218.         # obtenemos el mcd de los coeficientes del polinomio
  219.         mcd = self.mcd()
  220.  
  221.         # solo simplificamos si el mcd es diferente de 1
  222.         if mcd != 1:
  223.             nuevos_coeficientes = [] # lista para almacenar los nuevos coeficientes
  224.             # dividimos cada coeficiente por el mcd y lo añadimos a la lista de nuevos coeficientes
  225.             for coef in self.coeficientes:
  226.                 nuevos_coeficientes.append(coef // mcd)
  227.             # actualizamos los coeficientes del polinomio con los nuevos coeficientes simplificados
  228.             self.coeficientes = nuevos_coeficientes
  229.        
  230.     def raices_racionales(self):
  231.         # inicialización de la lista para almacenar posibles numeradores
  232.         numerador = []
  233.         # bucle para encontrar todos los enteros entre el negativo y positivo del último coeficiente
  234.         for i in range(-abs(self.coeficientes[-1]), abs(self.coeficientes[-1]) + 1):
  235.             if i != 0:  # excluimos el cero ya que no es un candidato válido para el numerador
  236.                 numerador.append(i)
  237.        
  238.         # inicialización de la lista para almacenar posibles denominadores
  239.         denominador = []
  240.         # bucle para encontrar todos los divisores del primer coeficiente
  241.         for i in range(1, abs(self.coeficientes[0]) + 1):
  242.             if self.coeficientes[0] % i == 0:  # si i es un divisor de coeficientes[0]
  243.                 denominador.append(i)
  244.        
  245.         # utilizamos un conjunto para evitar repetir candidatos
  246.         candidatos = set()
  247.         # doble bucle para dividir todos los numeradores posibles entre los denominadores
  248.         for numerador_valor in numerador:
  249.             for denominador_valor in denominador:
  250.                 candidato = numerador_valor // denominador_valor
  251.                 candidatos.add(candidato)  # añadimos el candidato al conjunto de candidatos
  252.        
  253.         # devolvemos el conjunto de candidatos posibles
  254.         return candidatos
  255.    
  256.     def ruffini(self, raiz):
  257.         # inicialización de la lista para almacenar los coeficientes resultantes
  258.         resultado = []
  259.         # el primer coeficiente siempre es parte del resultado
  260.         resultado.append(self.coeficientes[0])
  261.         # aplicamos la regla de ruffini para encontrar el resto de coeficientes
  262.         for coef in self.coeficientes[1:]:
  263.             # multiplicamos el último elemento de resultado por la raíz y sumamos el coeficiente actual
  264.             resultado.append(resultado[-1] * raiz + coef)
  265.        
  266.         # devolvemos dos cosas: el polinomio resultante y el residuo
  267.         # el polinomio resultante es todos menos el último término de resultado
  268.         # el último término de resultado es el residuo
  269.         return Polinomio(resultado[:-1]), resultado[-1]
  270.    
  271.     def factorizar(self):
  272.         # copia de los coeficientes para evitar modificar el polinomio original
  273.         coeficientes_copia = []
  274.         for coef in self.coeficientes:
  275.             coeficientes_copia.append(coef)
  276.  
  277.         # creación de una nueva variable de clase Polinomio con la copia de los coeficientes
  278.         coeficientes_copia = Polinomio(coeficientes_copia)
  279.  
  280.         # simplificación del polinomio si es necesario
  281.         coeficientes_copia.simplificar()
  282.  
  283.         # inicializamos la lista para almacenar los factores del polinomio
  284.         factores = []
  285.         # bucle para encontrar todos los factores
  286.         while len(coeficientes_copia.coeficientes) > 1:
  287.             # búsqueda de raíces racionales del polinomio
  288.             raices = coeficientes_copia.raices_racionales()
  289.             raiz_encontrada = None
  290.             # iteramos a través de las raíces potenciales
  291.             for r in raices:
  292.                 # uso del método de ruffini para reducir el polinomio por una raíz potencial
  293.                 polinomio_reducido, resto = coeficientes_copia.ruffini(r)
  294.                 if resto == 0:  # si el resto es 0, r es una raíz del polinomio
  295.                     raiz_encontrada = r
  296.                     # actualizamos los coeficientes del polinomio para reflejar la división
  297.                     coeficientes_copia.coeficientes = polinomio_reducido.coeficientes
  298.                     # registro del factor encontrado
  299.                     factores.append(f"x - {r}")
  300.                     break  # salimos del bucle ya que encontramos una raíz válida
  301.             if raiz_encontrada is None:
  302.                 break  # si no se encuentran más raíces racionales, terminamos el bucle
  303.  
  304.         # devolución de la lista de factores encontrados
  305.         return factores
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement