Página 1 de 1

Ecuaciones de 2º grado

Publicado: 15 May 2012, 13:37
por frp64
Hola, una forma de resolver ecuaciones de 2º grado del tipo: ax2 + bx + c = 0, mediante el uso de expresiones regulares:

Código: Seleccionar todo

#include <GUIConstants.au3>
#include <EditConstants.au3>

$gui = GUICreate ("Ecuaciones de 2º grado", 300, 100, -1, -1)
GUICtrlCreateLabel ("Ecuación:", 10, 10, 70, 20)
$entrada = GUICtrlCreateInput ("", 80, 10, 110, 20)
$boton = GUICtrlCreateButton ("Calcular", 200, 10, 90, 20)
GUICtrlCreateLabel ("x1:", 10, 40, 50, 20)
$ix1 = GUICtrlCreateInput ("", 80, 40, 70, 20, $ES_READONLY)
GUICtrlCreateLabel ("x2:", 10, 70, 50, 20)
$ix2 = GUICtrlCreateInput ("", 80, 70, 70, 20, $ES_READONLY)
GUISetState(@SW_SHOW, $gui)

While 1
	$msg = GUIGetMsg ()
	Switch $msg
		Case $boton
			$ecuacion = GUICtrlRead ($entrada)
			$resulta = StringRegExp ($ecuacion, "(\+|\-)*(\d)*(x2)(\+|\-)*(\d)*(x)(\+|\-)*(\d)*(\=)(0)", 1)
			If @error = 0 Then
				$a = StringRegExpReplace ($ecuacion, "(\+|\-)*(\d)*(x2)(\+|\-)*(\d)*(x)(\+|\-)*(\d)*(\=)(0)", "$1$2")
				$b = StringRegExpReplace ($ecuacion, "(\+|\-)*(\d)*(x2)(\+|\-)*(\d)*(x)(\+|\-)*(\d)*(\=)(0)", "$4$5")
				$c = StringRegExpReplace ($ecuacion, "(\+|\-)*(\d)*(x2)(\+|\-)*(\d)*(x)(\+|\-)*(\d)*(\=)(0)", "$7$8")
				$a = Number($a)
				$b = Number($b)
				$c = Number($c)
				$raiz = $b * $b + (4 * $a * $c)
				$raiz1 = - $b + Sqrt ($raiz)
				$raiz2 = - $b - Sqrt ($raiz)
				$x1 = Round($raiz1/(2*$a), 2)
				$x2 = Round($raiz2/(2*$a), 2)
				GUICtrlSetData ($ix1, $x1)
				GUICtrlSetData ($ix2, $x2)
				ConsoleWrite ("x2 = " & $x2 & @CRLF)
			ElseIf @error = 1 Then
				MsgBox (0, "Ecuaciones de 2º grado", "Error de ecuación, vuelve a introducirla")
				GUICtrlSetData ($entrada, "")
				ConsoleWrite ("No existe")
			EndIf
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd
Saludos

Re: Ecuaciones de 2º grado

Publicado: 28 May 2012, 09:59
por Ximorro
Uf, qué complejo lo de la ER, tengo que mirarla mejor porque seguramente puedes sacar los tres valores en una única llamada, cuando tenga un rato lo analizo y te digo a ver si la podemos simplificar.

ATENCIÓN: La fórmula está mal. :smt021
En la raíz has puesto $b * $b + (4 * $a * $c), pero es $b * $b - (4 * $a * $c), ojo con el "menos"

Hombre, al menos deberías haberla probado a ver si daba los resultados correctos :smt005

Re: Ecuaciones de 2º grado

Publicado: 28 May 2012, 11:00
por Ximorro
Mira ya lo he estado mirando y se puede simplificar bastante, te sugiero algunas cosas:

La original es esta:
(\+|\-)*(\d)*(x2)(\+|\-)*(\d)*(x)(\+|\-)*(\d)*(\=)(0)

.- Ni "-" ni "=" son especiales, no hace falta escaparlos.
.- Hay bastantes paréntesis que te puedes ahorrar, pues no añaden nada, como el de "(x2)", "(0)", etc.
.- También cosas como (\d)* puede ir sin paréntesis pues si haces \d* el asterisco afecta a todo el \d, no sólo a la d, pues \d es un identificador especial y se trata como una sóla cosa:
Con esos cambios ya tienes esta equivalente
(\+|-)*\d*x2(\+|-)*\d*x(\+|\-)*\d*=0

Bastante más corta ¿verdad? Esta es equivalente a la original, pero ambas versiones tienen algunos problemas:
Por ejemplo cuando haces "(\+|-)*", el * indica que puede haber cero o más signos, con lo que por ejemplo
+--+-23x2-+++-2x+++-1=0
se toma como ecuación correcta.

Hay que obligar a que tome "uno o ninguno" en el principio... ¡y uno obligatorio en medio! Si los del medio no los haces obligatorios se tomaría como correcto esto:
-21x23x5=0
Aunque sean + esos del medio deben ponerse.
Así que para arreglar lo de los signos hacemos el primero opcional (uno o cero) y los demás obligatorios:
(\+|-)?\d*x2(\+|-)\d*x(\+|-)\d*=0

El último problema es que al no estar la ER anclada a principio y final, si hay cosas antes y después de la ecuación se tomará como correcto, y puede liar las cosas, por ejemplo:
28--34x2+2x-1=0456
Para obligar a que empiece en el primer signo opcional y acabe en el =0 se ancla con los indicadores de inicio y fin de cadena:
^(\+|-)?\d*x2(\+|-)\d*x(\+|-)\d*=0$

Por supuesto me puedo equivocar pero creo que así hace lo que la primera y alguna cosa más.

MEJORAS propuestas (ojo que son cosas más o menos complicadas):
Aceptar números con decimales, no sólo enteros.
Permitir espacios por medio de la expresión.

Y luego están las más complicadas, que es los números opcionales (cuando un coeficiente vale 1 ó 0), pero eso es aún más complejo.


Para no juntarlo todo en el siguiente comentario te indico cómo sacar los tres coeficientes en una sólo llamada a StringRegExp.

Re: Ecuaciones de 2º grado

Publicado: 28 May 2012, 11:18
por Ximorro
Puedes usar el parámetro flag de StringRegExp a 1 ó 3 para tomar en un array todos los grupos capturados, así que lo que tenemos que hacer es poner un grupo para cada coeficiente a coger.

Un grupo es simplemente algo entre paréntesis.

Como hay cosas que tenemos que poner obligatoriamente entre paréntesis, por ejemplo lo de los signos por el OR, pero no queremos que esos grupos se capturen, se pone el prefijo "?:". Eso crea un grupo no capturable, y no saldrá en la solución.

Así que la ER capturando los tres coeficientes sería:
^((?:\+|-)?\d*)x2((?:\+|-)\d*)x((?:\+|-)\d*)=0$

Eso se usaría por ejemplo así:

Código: Seleccionar todo

$coefs = StringRegExp($ecuacion, "^((?:\+|-)?\d*)x2((?:\+|-)\d*)x((?:\+|-)\d*)=0$", 3)
$a = Number($coefs[0])
$b = Number($coefs[1])
$c = Number($coefs[2])

SUGERENCIA:
¿Por qué no amplías la cosa y das las soluciones complejas? esto es, cuando $raiz es negativo. Si has dado esas cosas, claro, si no sabes de lo que hablo nada, pero supongo que sí lo has dado.
Prueba por ejemplo
1x2+2x+3=0
(después de haber arreglado la fórmula de resolución, claro, sino nunca te dará raíz negativa)

EDITADO: Resimplificación
A veces nos complicamos más de lo que toca, la selección de signo se puede simplificar porque sólo implica tomar un carácter entre dos. Como es un sólo carácter se puede usar un conjunto en vez de un OR. Eso nos ayuda porque como ya no se hace un grupo no hay que poner lo de grupo no capturable.

Así que usando [+-] para seleccionar signo, en vez del OR, tenemos que la ER de toma de coeficientes:
^((?:\+|-)?\d*)x2((?:\+|-)\d*)x((?:\+|-)\d*)=0$
queda
^([+-]?\d*)x2([+-]\d*)x([+-]\d*)=0$

Mucho mejor al evitar los grupos no capturables.

En la ER de comprobación de sintaxis también se puede usar, no se simplifica tanto pero algo sirve:
^(\+|-)?\d*x2(\+|-)\d*x(\+|-)\d*=0$
queda
^[+-]?\d*x2[+-]\d*x[+-]\d*=0$

Re: Ecuaciones de 2º grado

Publicado: 26 Ene 2013, 12:41
por PDF
Buenas tuve el atrevimiento (con el permiso de frp64 y Ximorro) :smt003 , de modificar el script y crear un gui mas bonito con botones y ademas de agregar funciones parar resolver las ecuaciones del tipo AX2+BX+C=0, AX2+BX=0, AX2+C=0. Espero que no se molesten :smt002 . Saludos...

Re: Ecuaciones de 2º grado

Publicado: 28 Ene 2013, 12:30
por Ximorro
Hombre yo no me considero autor, sólo presté una ayuda concreta.
No creo que le importe tampoco al autor original, en realidad después del trabajo bastante amplio que hice estudiando la expresión regular ni contestó, y eso que le indicaba también que tenía mal la fórmula de resolución, así que supongo que abandonó el proyecto...

Te recomiendo mirar también mi último comentario, donde decía cómo simplificar la selección de signo con conjuntos.

Como ampliación te aconsejo que cuando las raíces sean complejas no dé como solución -1.#IND (= infinito). Di al menos que no tiene raíces reales y ya está.
Y para hacerlo aún mejor puedes calcular las raíces complejas.

Ale buen trabajo con el GUI.

Re: Ecuaciones de 2º grado

Publicado: 24 Feb 2014, 15:24
por PDF
Buenas...

Después de un buen tiempo decidí volver a mejorar esta aplicación inicialmente creada por frp64 y mejorada con la ayuda de Ximorro ...

Como me pareció muy interesante y muy util en mi caso, porque me daba flojera resolver las ecuaciones cuadráticas :smt033 , decidi mejorarla y presentarla en este hilo para quien lo necesite, le hice las correcciones que Ximorro sugirió y aquí esta la Versión 1.0.2.3
Calculadora 1.0.2.3
Calculadora 1.0.2.3
Calc.png (6.54 KiB) Visto 4211 veces
Especificaciones:

-Resuelve ecuaciones del tipo ax2+bx+c=0, ax2+bx=0 y ax2+c=0.
-Permite pegar y copiar el resultado

Desearía ir mejorandolo con la ayuda de ustedes...
Saludos

Re: Ecuaciones de 2º grado

Publicado: 24 Feb 2014, 16:01
por Dany
Excelente me gusta mucho :) Excelente trabajo.

Un pequeño problema al intentar resolver esta ecuación ecuación Imagen

me da este error

Imagen


Saludos muy bueno programa.

Re: Ecuaciones de 2º grado

Publicado: 24 Feb 2014, 16:20
por PDF
Si.. es un error Matematico ya que lo que ocurre es que al intentar resolver la ecuacion queda de esta forma:

x1= (-1+√-3
)/2 = No existe la raiz de un numero negativo entre lo nros reales..

x2= (-1-√-3)/2 = No existe la raiz de un numero negativo entre lo nros reales..

Saludos ..

Re: Ecuaciones de 2º grado

Publicado: 24 Feb 2014, 16:31
por Dany
mmmm bueno eso si pero la solucion seria esta:


Imagen


Saludos

Re: Ecuaciones de 2º grado

Publicado: 24 Feb 2014, 16:40
por PDF
Si, es que la aplicación muestra solo los resultados.

Tal vez la modifique para que muestre el proceso, como el de la imagen..

Re: Ecuaciones de 2º grado

Publicado: 24 Feb 2014, 16:58
por Dany
naaa creo que no es necesario el programita es una joya. saludos