Moin
In der SB war mal davon die Rede einen "Gleichungslöser" zu machen.
Das problem war dabei, dass es ziemlich kompliziert ist ein Programm zu schreiben, das Termumformungen beherrscht.
Also musste eine andere Methode her. ---> Ausprobieren
Mit dieser Methode arbeitet mein Skript.
Leider enthält es ein paar Bugs, sodass oftmals kein Ergebnis ausgegeben werden kann, weil die Annäherung an das Richtige Ergebnis im Sand verläuft.
Die Funktionsweise ist folgende:
Es gibt eine obere und Untere Schranke für das ergebnis.
Es wird mit beiden der Term gelöst und die Differenz zwichen den Beiden Seiten berechnet.
Dann werden die Schranken neu gesetzt, sodass sie das Richtige Ergebnis immer weiter einschränken, bis schließlich beide Schranken das ergebnis sind (Grenzwert)
Bei einigen Aufgaben Funktioniert das auch wunderbar, bei anderen wird eine Schranke Falsch gesetzt, wodurch das ergebnis außerhalb der Schranken liegt. Dann kann es auch nicht mehr erreicht werden.
Falls jemand viiel Zeit und auch etwas Lust dazu hat kann er sich meinen absolut Chaotischen Code mal reinziehen und auf Fehlersuche gehen^^
Falls jemand nur was so zum spaß haben will ist er hier auch richtig. Das Skript klappt zumindest manchmal kann bei Mathe Hausaufgaben den Taschenrechner aber noch nicht ersetzen^^
Spoiler anzeigen
#include <Misc.au3>
[/autoit] [autoit][/autoit] [autoit]Opt('GUICloseOnESC', 0)
Opt('GUIOnEventMode', 1)
Global $Kommastellen = 3, $Min = 0, $Max = 10000
[/autoit] [autoit][/autoit] [autoit]$hGUI = GUICreate('Gleichungslöser', 500, 200, _CenterX(500), _CenterY(200), -1, 0x00000080)
GUISetOnEvent(-3, '_Exit')
_Rahmen(3, 3, 494, 34, 2, '0x000000')
$hInput_1 = GUICtrlCreateEdit('', 5, 5, 490, 30, 64 + 1, 0)
GUICtrlSetFont($hInput_1, 18, 400, 0, 'Calibri', 5)
_Rahmen(3, 43, 494, 34, 2, '0x000000')
$hOutput_1 = GUICtrlCreateEdit('', 5, 45, 490, 30, 64 + 2049, 0)
GUICtrlSetFont($hOutput_1, 18, 400, 0, 'Calibri', 5)
_Rahmen(3, 83, 178, 34, 2, '0x000000')
GUICtrlCreateLabel('Ergebnisbereich:', 8, 85, 170, 30)
GUICtrlSetFont(-1, 18, 400, 0, 'Calibri', 5)
_Rahmen(3, 123, 58, 34, 2, '0x000000')
GUICtrlCreateLabel('Min:', 8, 125, 50, 30)
GUICtrlSetFont(-1, 18, 400, 0, 'Calibri', 5)
_Rahmen(59, 123, 193, 34, 2, '0x000000')
$hErg_Min = GUICtrlCreateEdit('-1000', 61, 125, 189, 30, 64 + 1, 0)
GUICtrlSetFont($hErg_Min, 18, 400, 0, 'Calibri', 5)
_Rahmen(250, 123, 59, 34, 2, '0x000000')
GUICtrlCreateLabel('Max:', 250 + 5, 125, 50, 30)
GUICtrlSetFont(-1, 18, 400, 0, 'Calibri', 5)
_Rahmen(250 + 57, 123, 190, 34, 2, '0x000000')
$hErg_Max = GUICtrlCreateEdit('1000', 250 + 59, 125, 186, 30, 64 + 1, 0)
GUICtrlSetFont($hErg_Max, 18, 400, 0, 'Calibri', 5)
_Rahmen(3, 163, 178, 34, 2, '0x000000')
GUICtrlCreateLabel('Kommastellen:', 8, 165, 170, 30)
GUICtrlSetFont(-1, 18, 400, 0, 'Calibri', 5)
_Rahmen(178 + 1, 163, 100, 34, 2, '0x0000000')
$Komma = GUICtrlCreateEdit('5', 181, 165, 96, 30, 64 + 1, 0)
GUICtrlSetFont(-1, 18, 400, 0, 'Calibri', 5)
;~ $Konsole = GUICtrlCreateEdit('', 500, 5, 395, 190)
[/autoit] [autoit][/autoit] [autoit]GUISetState(@SW_SHOW, $hGUI)
[/autoit] [autoit][/autoit] [autoit]While Sleep(25)
;~ If _IsPressed('02') Then GUICtrlSetData($Konsole, '')
If _IsPressed('0D') Then GUICtrlSetData($hOutput_1, 'X = ' & _Ausrechnen(GUICtrlRead($hInput_1)))
$Kommastellen = GUICtrlRead($Komma)
$Min = StringReplace(GUICtrlRead($hErg_Min),',', '.')
$Max = StringReplace(GUICtrlRead($hErg_Max),',', '.')
WEnd
Func _Diff($a)
If $a[0] > $a[1] Then
Return $a[0] - $a[1]
Else
Return $a[1] - $a[0]
EndIf
EndFunc ;==>_Diff
Func _Ausrechnen($sInput)
If StringInStr($sInput, '=') And StringInStr($sInput, 'x', 0) Then
$sInput = StringReplace($sInput, ',', '.')
$sInput = StringReplace($sInput, ')(', ')*(')
$sInput = StringReplace($sInput, 'x(', 'x*(')
$sInput = StringReplace($sInput, ')x', ')*x')
$sInput = StringReplace($sInput, '0x', '0*x')
$sInput = StringReplace($sInput, '1x', '1*x')
$sInput = StringReplace($sInput, '2x', '2*x')
$sInput = StringReplace($sInput, '3x', '3*x')
$sInput = StringReplace($sInput, '4x', '4*x')
$sInput = StringReplace($sInput, '5x', '5*x')
$sInput = StringReplace($sInput, '6x', '6*x')
$sInput = StringReplace($sInput, '7x', '7*x')
$sInput = StringReplace($sInput, '8x', '8*x')
$sInput = StringReplace($sInput, '9x', '9*x')
;~ ToolTip($sInput)
Local $Fertig = False, $Testzahl[3] = [$Min, ($Max+$Min)/2, $Max], $Diff[3] = [0, 0, 0], $Tmp[2], $Zahl, $Stop = False
Local $a = StringSplit($sInput, '=')
$a[1] = StringReplace($a[1], ' ', '', 0, 1)
$a[2] = StringReplace($a[2], ' ', '', 0, 1)
If $a[1] <> '' And $a[2] <> '' Then
Local $d[2], $b[2], $c[2]
[/autoit] [autoit][/autoit] [autoit]$Timer = TimerInit()
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]While $Fertig = False
If TimerDiff($Timer)/1000 > 3 Then Return 'Error - Das ergebnis konnte nicht ermittelt werden.'
;~ $Stop = False
[/autoit] [autoit][/autoit] [autoit]$d[0] = Execute(StringReplace($a[1], 'x', $Testzahl[0], 0, 0))
$d[1] = Execute(StringReplace($a[2], 'x', $Testzahl[0], 0, 0))
If Round($d[0], $Kommastellen) = Round($d[1], $Kommastellen) Then
$Fertig = True
$Zahl = $Testzahl[0]
Else
$Diff[0] = _Diff($d)
[/autoit] [autoit][/autoit] [autoit]$b[0] = Execute(StringReplace($a[1], 'x', $Testzahl[2], 0, 0))
$b[1] = Execute(StringReplace($a[2], 'x', $Testzahl[2], 0, 0))
If Round($b[0], $Kommastellen) = Round($b[1], $Kommastellen) Then
$Fertig = True
$Zahl = $Testzahl[2]
Else
$Diff[2] = _Diff($b)
[/autoit] [autoit][/autoit] [autoit]$c[0] = Execute(StringReplace($a[1], 'x', $Testzahl[1], 0, 0))
$c[1] = Execute(StringReplace($a[2], 'x', $Testzahl[1], 0, 0))
If Round($c[0], $Kommastellen) = Round($c[1], $Kommastellen) Then
$Fertig = True
$Zahl = $Testzahl[1]
Else
$Diff[1] = _Diff($c)
[/autoit] [autoit][/autoit] [autoit]$Tmp[0] = $Diff[0]
If $Diff[1] < $Tmp[0] Then $Tmp[0] = $Diff[1]
If $Diff[2] < $Tmp[0] Then $Tmp[0] = $Diff[2]
$Tmp[1] = $Diff[0]
If $Diff[1] > $Tmp[1] Then $Tmp[1] = $Diff[1]
If $Diff[2] > $Tmp[1] Then $Tmp[1] = $Diff[2]
_C(@CRLF & 'Diff Unten'& Round($Diff[0],$Kommastellen) &' Diff Mitte'& Round($Diff[1],$Kommastellen)&' Diff Oben'& Round($Diff[2],$Kommastellen))
[/autoit] [autoit][/autoit] [autoit]Switch String($Tmp[0])
[/autoit] [autoit][/autoit] [autoit]Case String($Diff[0])
_C(@CRLF & 'Unten am kleinsten')
;~ Sleep(500)
_C(@CRLF & Round($Diff[1],$Kommastellen) &' '& Round($Diff[2],$Kommastellen))
;~ Sleep(1500)
;~ If $Stop = False Then
If $Diff[1] < $Diff[2] Then
;Unten, Mitte, Oben
_C(@CRLF & 'Unten,Mitte,Oben')
If $Testzahl[0] < $Testzahl[1] Then
$Testzahl[2] = $Testzahl[1]
Else
$Testzahl[2] = $Testzahl[0]
$Testzahl[0] = $Testzahl[1]
EndIf
;~ $Stop = True
Else
;Unten, Oben, Mitte
;~ If $Testzahl[0] > $Testzahl[2] Then
;~
;~ $Testzahl[1] = $Testzahl[2]
EndIf
;~ EndIf
Case String($Diff[1])
_C(@CRLF & 'Mitte am kleinsten')
;~ If $Stop = False Then
_C(@CRLF & Round($Diff[0],$Kommastellen) &' '& Round($Diff[2],$Kommastellen))
If $Diff[0] < $Diff[2] Then
;Mitte,Unten,Oben
_C(@CRLF & 'Mitte,unten,oben')
If $Testzahl[0] < $Testzahl[1] Then
$Testzahl[2] = $Testzahl[1]
Else
$Testzahl[2] = $Testzahl[0]
$Testzahl[0] = $Testzahl[1]
EndIf
;~ $Testzahl[0] = $Testzahl[1]
;~ $Stop = True
Else
;Mitte,Oben,Unten
_C(@CRLF & 'Mitte,oben,unten')
If $Testzahl[1] < $Testzahl[2] Then
$Testzahl[0] = $Testzahl[1]
Else
$Testzahl[0] = $Testzahl[2]
$Testzahl[2] = $Testzahl[1]
EndIf
;~ $Stop = True
EndIf
;~ EndIf
Case String($Diff[2])
_C(@CRLF & 'Oben am kleinsten')
;~ If $Stop = False Then
If $Diff[0] < $Diff[1] Then
;Oben, Unten, Mitte
;~ $Testzahl[1] = $Testzahl[2]
;~ $Testzahl[2] = $Testzahl[0]
;~ $Testzahl[0] = $Testzahl[1]
Else
;Oben, Mitte, Unten
_C(@CRLF & 'Oben,Mitte,Unten')
If $Testzahl[1] < $Testzahl[2] Then
$Testzahl[0] = $Testzahl[1]
Else
$Testzahl[0] = $Testzahl[2]
$Testzahl[2] = $Testzahl[1]
EndIf
;~ $Stop = True
EndIf
;~ EndIf
EndSwitch
[/autoit] [autoit][/autoit] [autoit]$Testzahl[1] = ($Testzahl[0] + $Testzahl[2]) / 2
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]EndIf
EndIf
EndIf
;~ If $Diff[0] And $Diff[1] And $Diff[2] = 0 Then $Fertig = True
[/autoit] [autoit][/autoit] [autoit]_C(@CRLF & 'Zusammenfassung' & @CRLF & Round($d[0],$Kommastellen) & '-' & Round($d[1],$Kommastellen) & '=' & Round($Diff[0],$Kommastellen) & @CRLF & Round($b[0],$Kommastellen) & '-' & Round($b[1],$Kommastellen) & '=' & Round($Diff[2],$Kommastellen) & @CRLF & Round($c[0],$Kommastellen) & '-' & Round($c[1],$Kommastellen) & '=' & Round($Diff[1],$Kommastellen) & @CRLF & Round($Testzahl[0],$Kommastellen) & ' ' & Round($Testzahl[1],$Kommastellen) & ' ' & Round($Testzahl[2],$Kommastellen))
;~ Sleep(1000)
WEnd
Return Round($Zahl, $Kommastellen)
[/autoit] [autoit][/autoit] [autoit];~ ToolTip($a[1] &' '& $a[2])
EndIf
EndIf
EndFunc ;==>_Ausrechnen
Func _C($sText)
;~ GUICtrlSetData($Konsole, $sText, 1)
EndFunc
Func _Rahmen($links, $oben, $breite, $hoehe, $strichstaerke, $farbe)
Local $a[8]
$a[0] = GUICtrlCreateLabel("", $links, $oben, $breite, $strichstaerke)
$a[1] = GUICtrlSetBkColor(-1, $farbe)
$a[2] = GUICtrlCreateLabel("", $links, $oben, $strichstaerke, $hoehe)
$a[3] = GUICtrlSetBkColor(-1, $farbe)
$a[4] = GUICtrlCreateLabel("", $links + $breite - $strichstaerke, $oben, $strichstaerke, $hoehe)
$a[5] = GUICtrlSetBkColor(-1, $farbe)
$a[6] = GUICtrlCreateLabel("", $links, $oben + $hoehe - $strichstaerke, $breite, $strichstaerke)
$a[7] = GUICtrlSetBkColor(-1, $farbe)
Local $Return = 1
If $a[1] + $a[3] + $a[5] + $a[7] <> 4 Then $Return = 0
For $i = 0 To 6 Step 2
If $a[$i] = 0 Then $Return = 0
Next
Return $Return
EndFunc ;==>_Rahmen
Func _Exit()
Exit
EndFunc ;==>_Exit
Func _CenterX($a)
Return @DesktopWidth / 2 - $a / 2
EndFunc ;==>_CenterX
Func _CenterY($a)
Return @DesktopHeight / 2 - $a / 2
EndFunc ;==>_CenterY
[Blockierte Grafik: http://img3.imagebanana.com/img/qf9gvf9l/Document0009.png]
[Blockierte Grafik: http://img3.imagebanana.com/img/h8ruboa6/Document0081.png]
Hier sieht man eine relativ komplexe gleichung (für anfänger :P) die gelöst wurde. (Hoffentlich korrekt^^)
PS: Die Berechnung kann man durch dücken von Enter Starten !
Update1: Es werden nun auch Kommas verwendet. (z.B. 5,5 kann man jetzt auch nutzen statt 5.5)
Update2: Man kann nun das Multiplizierenzeichen bei einigen Stellen weglassen. ( z.B. 5x = 5*x oder (x+1)(x-1) = (x+1)*(x-1) )
Anmerkung: Oftmals kann das Ergebnis nicht ausgegeben werden, da die Schranken manchmal Falsch gesetzt werden, sodass das ergebnis außerhalb dieser liegt. Wenn man das ergebnis in etwa kennt kann man die Schranken vorher schon etwas einstellen. Dann klappt es manchmal^^
mfg
Mars(i)