AutID Posted November 22, 2014 Share Posted November 22, 2014 I am not sure how to explain this so I will show Local $eq = (8 + (7 * 4) - (3 *(2 / 7))) ConsoleWrite($eq & @LF) ; Calculation of equation ; (8 + (7 * 4) - (3 *(2 / 7))) ; (8 + 28) - (3 * 0.2857142857142857) ; 36 - 0.8571428571428571 I could write a small function if the equation I am dealing with would be a standard one but there are thousands of equations. So I would have to analyse all of them and then return some results. Anyone ever heard of a DLL or an UDF that is capable to do this? https://iblockify.wordpress.com/ Link to comment Share on other sites More sharing options...
Jfish Posted November 22, 2014 Share Posted November 22, 2014 Are you asking if there is a standard set of equations somewhere? Could you be more specific? What kind of equations? Or are you asking something different? Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
AutID Posted November 22, 2014 Author Share Posted November 22, 2014 (edited) I will be handling math calculations such as the one in post 1, or different. For autoit it is easy to retrieve the results. However I want to analyse how we got the result. To see how it is done. How the calculation is done, how the entire process is done. Something like this I suppose Edit: let me put the code together #include <Array.au3> Local $eq = (8 + (7 * 4) - (3 *(2 / 7))) ConsoleWrite($eq & @LF) Local $eq2 = _EquationAnalysedResult($eq) If IsArray($eq2) Then _ArrayDisplay($eq2) Func _EquationAnalysedResult($equation) ; do the calculation ; Calculation of equation ; (8 + (7 * 4) - (3 *(2 / 7))) ; (8 + 28) - (3 * 0.2857142857142857) ; 36 - 0.8571428571428571 ; return an array with the entire process as above Return $equation EndFunc Edited November 22, 2014 by AutID https://iblockify.wordpress.com/ Link to comment Share on other sites More sharing options...
czardas Posted November 22, 2014 Share Posted November 22, 2014 Basically an equation is two expressions which are numerically equal, and the possibilities are endless. I remember Mat did some factorization (with quadratics - I think), but that was quite a while ago. Looking at your example, I see you can remove all the brackets and still get the same answer. There's a clue in there somewhere. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
Jfish Posted November 22, 2014 Share Posted November 22, 2014 You basically need to show the precedence as it is being executed highest to lowest as in the help file, correct? From highest precedence to lowest: Not ^ * / + - & < > <= >= = <> == And Or Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
AutID Posted November 22, 2014 Author Share Posted November 22, 2014 (edited) You basically need to show the precedence as it is being executed highest to lowest as in the help file, correct? Yes if I am understanding that correctly. Edit: Like in the post 3. Edited November 22, 2014 by AutID https://iblockify.wordpress.com/ Link to comment Share on other sites More sharing options...
iamtheky Posted November 22, 2014 Share Posted November 22, 2014 (edited) Dividing into order of operations seems wayyyy difficult. Simplifying sections between operators much less so,but still probably a thousand edge cases to break it. --Use wolfram to do your homework like everyone else Edited November 22, 2014 by boththose ,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-. |(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/ (_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_) | | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) ( | | | | |)| | \ / | | | | | |)| | `--. | |) \ | | `-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_| '-' '-' (__) (__) (_) (__) Link to comment Share on other sites More sharing options...
Jfish Posted November 22, 2014 Share Posted November 22, 2014 Does seem hard, this would be an approach to grab all the unique parens operations (convert to a string and then parse): #include <Array.au3> #include <String.au3> $eq = "(8 + (7 * 4) - (3 *(2 / 7)))" func _parseEquation($eq) $parens=_StringBetween ($eq,"(",")") for $a=0 to ubound($parens) -1 $parens[$a]&=")" next _ArrayDisplay($parens) EndFunc _parseEquation($eq) But that still leaves a lot of work to be done to grab all the operators in the order of precedence. It is a start ... Build your own poker game with AutoIt: pokerlogic.au3 | Learn To Program Using FREE Tools with AutoIt Link to comment Share on other sites More sharing options...
UEZ Posted November 22, 2014 Share Posted November 22, 2014 I would try it with >shunting-yard-algorithm. Br,UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 22, 2014 Moderators Share Posted November 22, 2014 (edited) I'm sure there are many ways to break this (especially considering I only did add/subtract/division/multiplication), I'll leave it to you all to break it. Edit: Found another breaking point lol, I'm done looking expandcollapse popup#include <Array.au3> Global $gsz_equation = "(8 + (7 * 4) - (3 *(2 / 7)))" Global $ga_ret = _ProcessSimpleEquation($gsz_equation) _ArrayDisplay($ga_ret) ; to console For $i = 1 To UBound($ga_ret) - 1 ConsoleWrite($ga_ret[$i] & @CRLF) Next Func _ProcessSimpleEquation($s_eq) $s_eq = StringReplace($s_eq, " ", "") Local $s_tmp = $s_eq, $a_tmp Local $s_ret = StringRegExpReplace($s_eq, "(\+|\-|\*|/)", " $1 ") & @LF ; get mult/div with digits on both sides $a_tmp = StringRegExp($s_tmp, "((?:\d*\.?\d*)(?<=\d)[\*/](?:\d*\.?\d*))", 3) If Not @error Then For $i = 0 To UBound($a_tmp) - 1 $s_tmp = StringRegExpReplace($s_tmp, "\b\Q" & $a_tmp[$i] & "\E\b", Execute($a_tmp[$i])) Next ; format string $s_ret &= StringRegExpReplace($s_tmp, "(\+|\-|\*|/)", " $1 ") & @LF EndIf ; get mult/div from possible parenth left over $a_tmp = StringRegExp($s_tmp, "(\(?(?:\d*\.?\d*)(?<=\d)[\*/]\(?(?:\d*\.?\d*))", 3) If Not @error Then ; add parenthesis For $i = 0 To UBound($a_tmp) -1 StringReplace($a_tmp[$i], "(", "") For $j = 2 To @extended $a_tmp[$i] &= ")" Next $a_tmp[$i] = StringTrimLeft($a_tmp[$i], 1) $s_tmp = StringRegExpReplace($s_tmp, "\Q" & $a_tmp[$i] & "\E", Execute($a_tmp[$i])) Next ; format string $s_ret &= StringRegExpReplace($s_tmp, "(\+|\-|\*|/)", " $1 ") & @LF EndIf ; on to addition/subtraction While 1 $a_tmp = StringRegExp($s_tmp, "((?:\d*\.?\d*)(?<=\d)[\-\+]\(?(?:\d*\.?\d*)(?<=\d)\)?)", 3) If @error Then ExitLoop For $i = 0 To UBound($a_tmp) - 1 $s_tmp = StringRegExpReplace($s_tmp, "\Q" & $a_tmp[$i] & "\E", Execute($a_tmp[$i])) Next ; format string $s_ret &= StringRegExpReplace($s_tmp, "(\+|\-|\*|/)", " $1 ") & @LF WEnd ; we are going to return an array $a_tmp = StringSplit(StringTrimRight($s_ret, 1), @LF) $a_tmp[$a_tmp[0]] = Execute($a_tmp[$a_tmp[0]]) Return $a_tmp EndFunc .. Edited November 22, 2014 by SmOke_N Jfish 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
mikell Posted November 22, 2014 Share Posted November 22, 2014 (edited) Assuming parenthesis are placed with art and correctly something like this should work $eq = "(8 + (7 * 4)) - (3 *(2 / 7))" $res = $eq & @crlf&@crlf StringReplace($eq, "(", "") $p1 = @extended StringReplace($eq, ")", "") $p2 = @extended If $p1<>$p2 Then Exit Msgbox(0,"", "parenthesis error") For $i = 1 to $p1 $sub = (Mod($i, 2)=0) ? StringRegExpReplace($eq, '.*(\([^\(\)]*?\)).*?\)*', '$1') : _ StringRegExpReplace($eq, '.*?(\([^\(\)]*?\)).*', '$1') $eq = StringReplace($eq, $sub, Execute($sub) ) $res &= $eq & @crlf Next $res &= Execute($eq) Msgbox(0,"", $res) Edit and using operators precedence Edited November 22, 2014 by mikell Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 22, 2014 Moderators Share Posted November 22, 2014 (edited) Nice Edit: Mikell, I remember why I stopped doing a similar approach. For $eq, use something like 8 + 9 * 3, without parenthesis. I believe the OP wanted to see the break down of the math itself, not just the answer(s). Edit2: Alas, mine doesn't process without parenthesis with an equation like: 8 + 9 * 3 * 4 either. Edited November 22, 2014 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
AutID Posted November 23, 2014 Author Share Posted November 23, 2014 First of all thanks to everyone for the help. I would try it with >shunting-yard-algorithm. Br, UEZ hmmm, I am not sure it could help me with a quick look I had. May get deeper into that. I'm sure there are many ways to break this (especially considering I only did add/subtract/division/multiplication), I'll leave it to you all to break it. Edit: Found another breaking point lol, I'm done looking expandcollapse popup#include <Array.au3> Global $gsz_equation = "(8 + (7 * 4) - (3 *(2 / 7)))" Global $ga_ret = _ProcessSimpleEquation($gsz_equation) _ArrayDisplay($ga_ret) ; to console For $i = 1 To UBound($ga_ret) - 1 ConsoleWrite($ga_ret[$i] & @CRLF) Next Func _ProcessSimpleEquation($s_eq) $s_eq = StringReplace($s_eq, " ", "") Local $s_tmp = $s_eq, $a_tmp Local $s_ret = StringRegExpReplace($s_eq, "(\+|\-|\*|/)", " $1 ") & @LF ; get mult/div with digits on both sides $a_tmp = StringRegExp($s_tmp, "((?:\d*\.?\d*)(?<=\d)[\*/](?:\d*\.?\d*))", 3) If Not @error Then For $i = 0 To UBound($a_tmp) - 1 $s_tmp = StringRegExpReplace($s_tmp, "\b\Q" & $a_tmp[$i] & "\E\b", Execute($a_tmp[$i])) Next ; format string $s_ret &= StringRegExpReplace($s_tmp, "(\+|\-|\*|/)", " $1 ") & @LF EndIf ; get mult/div from possible parenth left over $a_tmp = StringRegExp($s_tmp, "(\(?(?:\d*\.?\d*)(?<=\d)[\*/]\(?(?:\d*\.?\d*))", 3) If Not @error Then ; add parenthesis For $i = 0 To UBound($a_tmp) -1 StringReplace($a_tmp[$i], "(", "") For $j = 2 To @extended $a_tmp[$i] &= ")" Next $a_tmp[$i] = StringTrimLeft($a_tmp[$i], 1) $s_tmp = StringRegExpReplace($s_tmp, "\Q" & $a_tmp[$i] & "\E", Execute($a_tmp[$i])) Next ; format string $s_ret &= StringRegExpReplace($s_tmp, "(\+|\-|\*|/)", " $1 ") & @LF EndIf ; on to addition/subtraction While 1 $a_tmp = StringRegExp($s_tmp, "((?:\d*\.?\d*)(?<=\d)[\-\+]\(?(?:\d*\.?\d*)(?<=\d)\)?)", 3) If @error Then ExitLoop For $i = 0 To UBound($a_tmp) - 1 $s_tmp = StringRegExpReplace($s_tmp, "\Q" & $a_tmp[$i] & "\E", Execute($a_tmp[$i])) Next ; format string $s_ret &= StringRegExpReplace($s_tmp, "(\+|\-|\*|/)", " $1 ") & @LF WEnd ; we are going to return an array $a_tmp = StringSplit(StringTrimRight($s_ret, 1), @LF) $a_tmp[$a_tmp[0]] = Execute($a_tmp[$a_tmp[0]]) Return $a_tmp EndFunc .. Smoke try adding one more parenthesis to the equation. I said the equation will be similar as the one in post on but not exactly the same. Your example is very good and will work very good with the same number of parenthesis or less, but not with more. I could fix it but I understand nothing about regex, it is simply beyond my head so quitted long time ago. Assuming parenthesis are placed with art and correctly something like this should work $eq = "(8 + (7 * 4)) - (3 *(2 / 7))" $res = $eq & @crlf&@crlf StringReplace($eq, "(", "") $p1 = @extended StringReplace($eq, ")", "") $p2 = @extended If $p1<>$p2 Then Exit Msgbox(0,"", "parenthesis error") For $i = 1 to $p1 $sub = (Mod($i, 2)=0) ? StringRegExpReplace($eq, '.*(\([^\(\)]*?\)).*?\)*', '$1') : _ StringRegExpReplace($eq, '.*?(\([^\(\)]*?\)).*', '$1') $eq = StringReplace($eq, $sub, Execute($sub) ) $res &= $eq & @crlf Next $res &= Execute($eq) Msgbox(0,"", $res) Edit and using operators precedence This seems to work very good actually. It will give a good result with a lot of different equations I tried however the break down isn't so accurate. Try this and check the break down, "(8 + (7 * 4)) - (3 - (9 * 3) *(2 / (7 * 7)))" https://iblockify.wordpress.com/ Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 23, 2014 Moderators Share Posted November 23, 2014 Well, I went cross-eyed with the regex, and went back old school. I can see it breaking if the math fails (if values exceed scope). expandcollapse popupGlobal $ga_Equation[4] = [ _ "(8 + (7 * ((3 / 4) * (5 / (2 ^ (4 ^ 2))))))", _ "8 + 7 * 3 / 4 * 5 / 2 ^ 2 ^ 2", _ "8 + (7 * ((3 / 4) * (5 / (4 ^ 2))))", _ "8 + 7 * 4 - 3 *2 / 7 + 2^3"] Global $ga_Arr = 0 For $i = 0 To UBound($ga_Equation) - 1 $ga_Arr = _getMathBreakDown($ga_Equation[$i]) _simpleArray2Cons($ga_Arr, 1) ConsoleWrite("----" & @CRLF) Next Func _getMathBreakDown($s_str) Local $s_ret = $s_str While 1 $s_tmp = __getParenthesisItems($s_str) If @error Then ExitLoop $s_str = StringRegExpReplace($s_str, "\Q" & $s_tmp & "\E", Execute($s_tmp), 1) $s_ret &= @LF & $s_str WEnd Local $a_ret If $s_ret = $s_str Then ; we don't want to assume how they want to process ; the numbers sent, so parenthesis are their responsibility ; however, if they sent something with no parenthesis ; it might be fun to show them what the break down is like ; from the programs translator ; Order: ; ^, /, *, +, - ; recursion fun!!! :) $a_ret = _getMathBreakDown(_setParenthesisMathItems($s_str)) $s_ret = $s_str For $i = 1 To UBound($a_ret) - 1 If StringLen($a_ret[$i]) Then $s_ret &= @LF & $a_ret[$i] Next $s_str = $a_ret[UBound($a_ret)-1] EndIf If Not StringRegExp($s_str, "^(\d+\.?\d*|\d*\.?\d+)\z") Then $s_ret &= @LF & Execute($s_str) EndIf $a_ret = StringSplit($s_ret, @LF) Return $a_ret EndFunc Func _setParenthesisMathItems($s_str) Local Const $a_items[] = ["^","/","*","+","-"] Local $s_tmp = $s_str Local $a_ret[100][2], $a_tmp, $i_cc = 0 For $i = 0 To UBound($a_items) - 1 $a_tmp = __setParenthesisMathItems($s_str, $a_items[$i]) If Not @error Then If Mod($i_cc + 1, 100) = 0 Then ReDim $a_ret[$i_cc + 101][2] EndIf For $n = 0 To UBound($a_tmp) - 1 $a_ret[$i_cc][0] = $a_tmp[$n][0] $a_ret[$i_cc][1] = $a_tmp[$n][1] $i_cc += 1 Next EndIf Next ReDim $a_ret[$i_cc][2] If $s_str = $s_tmp Then ; error??? Return SetError(1, 0, $s_tmp) EndIf For $i = UBound($a_ret) - 1 To 0 Step - 1 $s_str = StringReplace($s_str, $a_ret[$i][0], $a_ret[$i][1], 1, 1) Next Return $s_str EndFunc Func __setParenthesisMathItems(ByRef $s_str, $s_item) Local Const $a_items[] = ["^","/","*","+","-"] Local Const $a_repitems[] = ["p","d","m","a","s"] Local $s_repl = "" For $i = 0 To UBound($a_items) - 1 If $s_item = $a_items[$i] Then $s_repl = "rep" & $a_repitems[$i] ExitLoop EndIf Next StringReplace($s_str, $s_item, "") Local $n_items = @extended If Not $n_items Then Return SetError(1, 0, 0) EndIf Local $a_temp = 0, $s_last, $a_reg, $n_ub Local $i_cc = 0, $s_repn = "", $s_tmp = $s_str While 1 $a_reg = StringRegExp($s_str, "((?:\d*\.?\d+|\d+\.?\d*|rep.\d+)\s*\" & $s_item & "\s*)", 3) If @error Then ExitLoop $n_ub = UBound($a_reg) - 1 $a_temp = StringRegExp($s_str, "(\Q" & $a_reg[$n_ub] & "\E(?:\d*\.?\d+|\d+\.?\d*|rep.\d+))", 3) If @error Then ExitLoop $s_str = StringReplace($s_str, $a_temp[0], $s_repl & $i_cc, -1, 1) $s_repn &= "(" & $a_temp[0] & ")|" & $s_repl & $i_cc & @LF $i_cc += 1 WEnd If $s_str = $s_tmp Then Return SetError(2, 0, 0) EndIf Local $a_split = StringSplit(StringTrimRight($s_repn, 1), @LF, 2) Local $a_ret[UBound($a_split)][2], $i_cc = 0 For $i = 0 To UBound($a_split) - 1 $a_tmp = StringSplit($a_split[$i], "|") $a_ret[$i][0] = $a_tmp[2] $a_ret[$i][1] = $a_tmp[1] Next Return $a_ret EndFunc Func __getParenthesisItems($s_str) StringReplace($s_str, "(", "") Local $n_parenthesis = @extended If Not $n_parenthesis Then Return SetError(1, 0, 0) EndIf StringReplace($s_str, ")", "") If @extended <> $n_parenthesis Then Return SetError(1, 0, 0) EndIf Local $s_tmp Local $i_lftpos = 0, $i_rgtpos = 0 $i_lftpos = StringInStr($s_str, "(", 0, $n_parenthesis) $s_tmp = StringTrimLeft($s_str, $i_lftpos - 1) $i_rgtpos = StringInStr($s_tmp, ")", 0, 1) Return StringMid($s_str, $i_lftpos, $i_rgtpos) EndFunc Func _simpleArray2Cons(ByRef $a_arr, $n_istart = 0, $n_jstart = 0) Local $n_ub1 = UBound($a_arr) If $n_ub1 = 0 Then Return SetError(1) Local $n_ub2 = UBound($a_arr, 2) Local $s_toconsole If $n_ub2 Then For $i = $n_istart To $n_ub1 - 1 For $j = $n_jstart To $n_ub2 - 1 $s_toconsole &= "[" & $i & "][" & $j & "] = " & $a_arr[$i][$j] & @CRLF Next ConsoleWrite($s_toconsole) $s_toconsole = "" Next Return EndIf For $i = $n_istart To $n_ub1 - 1 $s_toconsole &= "[" & $i & "] = " & $a_arr[$i] & @CRLF Next ConsoleWrite($s_toconsole) EndFunc AutID 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted November 23, 2014 Moderators Share Posted November 23, 2014 And yet more... had to format those strings that didn't have all the brackets correctly ... and this stupid string obsession is over... if you find the errors, you fix'em expandcollapse popupGlobal $ga_Equation[] = [ _ "(8 + (7 * 4) - (3 *(2 / 7)))", _ "8 + 7 * 4 - 3 * 2 / 7", _ "8 + 7 * (4 - 3) * 2 / 7"] Global $ga_Arr = 0 For $i = 0 To UBound($ga_Equation) - 1 $ga_Arr = _getMathBreakDown($ga_Equation[$i]) _simpleArray2Cons($ga_Arr, 1) ConsoleWrite("----" & @CRLF) Next Func _getMathBreakDown($s_str) Local $s_ret = $s_str Local $s_hold = $s_str Local $s_tmp = __formatMathBreakDown($s_str) If $s_tmp <> $s_str Then $s_ret &= @LF & $s_tmp $s_str = $s_tmp EndIf While 1 $s_tmp = __getParenthesisItems($s_str) If @error Then ExitLoop $s_str = StringRegExpReplace($s_str, "\Q" & $s_tmp & "\E", Execute($s_tmp), 1) $s_ret &= @LF & $s_str WEnd Local $a_ret StringRegExpReplace($s_str, "[\*\-\+\^/]", "") If @extended > 1 Or $s_ret = $s_str Then ; we don't want to assume how they want to process ; the numbers sent, so parenthesis are their responsibility ; however, if they sent something with no parenthesis ; it might be fun to show them what the break down is like ; from the programs translator ; Order: ; ^, /, *, +, - ; recursion fun!!! :) $a_ret = _getMathBreakDown(_setParenthesisMathItems($s_str)) $s_ret = $s_hold <> $s_str ? $s_hold & @LF & $s_str : $s_str For $i = 1 To UBound($a_ret) - 1 If StringLen($a_ret[$i]) Then $s_ret &= @LF & $a_ret[$i] Next $s_str = $a_ret[UBound($a_ret)-1] EndIf If Not StringRegExp($s_str, "^(\d+\.?\d*|\d*\.?\d+)\z") Then $s_ret &= @LF & Execute($s_str) EndIf $a_ret = StringSplit($s_ret, @LF) Return $a_ret EndFunc Func _setParenthesisMathItems($s_str) Local Const $a_items[] = ["^","/","*","+","-"] Local $s_tmp = $s_str Local $a_ret[100][2], $a_tmp, $i_cc = 0 For $i = 0 To UBound($a_items) - 1 $a_tmp = __setParenthesisMathItems($s_str, $a_items[$i]) If Not @error Then If Mod($i_cc + 1, 100) = 0 Then ReDim $a_ret[$i_cc + 101][2] EndIf For $n = 0 To UBound($a_tmp) - 1 $a_ret[$i_cc][0] = $a_tmp[$n][0] $a_ret[$i_cc][1] = $a_tmp[$n][1] $i_cc += 1 Next EndIf Next ReDim $a_ret[$i_cc][2] If $s_str = $s_tmp Then ; error??? Return SetError(1, 0, $s_tmp) EndIf For $i = UBound($a_ret) - 1 To 0 Step - 1 $s_str = StringReplace($s_str, $a_ret[$i][0], $a_ret[$i][1], 1, 1) Next Return $s_str EndFunc Func __setParenthesisMathItems(ByRef $s_str, $s_item) Local Const $a_items[] = ["^","/","*","+","-"] Local Const $a_repitems[] = ["p","d","m","a","s"] Local $s_repl = "" For $i = 0 To UBound($a_items) - 1 If $s_item = $a_items[$i] Then $s_repl = "rep" & $a_repitems[$i] ExitLoop EndIf Next StringReplace($s_str, $s_item, "") Local $n_items = @extended If Not $n_items Then Return SetError(1, 0, 0) EndIf Local $a_temp = 0, $s_last, $a_reg, $n_ub Local $i_cc = 0, $s_repn = "", $s_tmp = $s_str While 1 $a_reg = StringRegExp($s_str, "((?:\d*\.?\d+|\d+\.?\d*|rep.\d+)\s*\" & $s_item & "\s*)", 3) If @error Then ExitLoop $n_ub = UBound($a_reg) - 1 $a_temp = StringRegExp($s_str, "(\Q" & $a_reg[$n_ub] & "\E(?:\d*\.?\d+|\d+\.?\d*|rep.\d+))", 3) If @error Then ExitLoop $s_str = StringReplace($s_str, $a_temp[0], $s_repl & StringFormat("%04d", $i_cc), -1, 1) $s_repn &= "(" & $a_temp[0] & ")|" & $s_repl & StringFormat("%04d", $i_cc) & @LF $i_cc += 1 WEnd If $s_str = $s_tmp Then Return SetError(2, 0, 0) EndIf Local $a_split = StringSplit(StringTrimRight($s_repn, 1), @LF, 2) Local $a_ret[UBound($a_split)][2], $i_cc = 0 For $i = 0 To UBound($a_split) - 1 $a_tmp = StringSplit($a_split[$i], "|") $a_ret[$i][0] = $a_tmp[2] $a_ret[$i][1] = $a_tmp[1] Next Return $a_ret EndFunc Func __getParenthesisItems($s_str) StringReplace($s_str, "(", "") Local $n_parenthesis = @extended If Not $n_parenthesis Then Return SetError(1, 0, 0) EndIf StringReplace($s_str, ")", "") If @extended <> $n_parenthesis Then Return SetError(1, 0, 0) EndIf Local $s_tmp Local $i_lftpos = 0, $i_rgtpos = 0 $i_lftpos = StringInStr($s_str, "(", 0, $n_parenthesis) $s_tmp = StringTrimLeft($s_str, $i_lftpos - 1) $i_rgtpos = StringInStr($s_tmp, ")", 0, 1) Return StringMid($s_str, $i_lftpos, $i_rgtpos) EndFunc Func __formatMathBreakDown($s_str) $s_str = StringStripWS($s_str, 7) Local $s_change = $s_str, $s_out Local $i_cc = 0, $i_ub Local $a_tmp, $a_tmp2, $a_split If StringInStr($s_str, "(", 1, 1) Then While 1 $s_tmp = __getParenthesisItems($s_change) If @error Then ExitLoop $s_change = StringReplace($s_change, $s_tmp, "rep" & StringFormat("%04d", $i_cc)) $s_out &= $s_tmp & "|" & "rep" & StringFormat("%04d", $i_cc) & @LF $i_cc += 1 WEnd $a_tmp = StringSplit(StringTrimRight($s_out, 1), @LF) Dim $a_tmp2[UBound($a_tmp) - 1][2] $i_ub = UBound($a_tmp2) For $i = 1 To UBound($a_tmp) - 1 $a_split = StringSplit($a_tmp[$i], "|") $a_tmp2[$i - 1][0] = $a_split[2] $a_tmp2[$i - 1][1] = $a_split[1] Next StringRegExpReplace($a_tmp2[$i_ub-1][1], "[\*\-\+\^/]", "") If @extended > 1 Then $a_tmp2[$i_ub - 1][1] = _setParenthesisMathItems( _ StringRegExpReplace($a_tmp2[$i_ub - 1][1], "\(|\)", "")) EndIf For $i = UBound($a_tmp2) - 1 To 0 Step -1 $s_change = StringReplace($s_change, $a_tmp2[$i][0], $a_tmp2[$i][1]) Next Return $s_change EndIf Return _setParenthesisMathItems($s_str) EndFunc Func _simpleArray2Cons(ByRef $a_arr, $n_istart = 0, $n_jstart = 0) Local $n_ub1 = UBound($a_arr) If $n_ub1 = 0 Then Return SetError(1) Local $n_ub2 = UBound($a_arr, 2) Local $s_toconsole If $n_ub2 Then For $i = $n_istart To $n_ub1 - 1 For $j = $n_jstart To $n_ub2 - 1 $s_toconsole &= "[" & $i & "][" & $j & "] = " & $a_arr[$i][$j] & @CRLF Next ConsoleWrite($s_toconsole) $s_toconsole = "" Next Return EndIf For $i = $n_istart To $n_ub1 - 1 $s_toconsole &= "[" & $i & "] = " & $a_arr[$i] & @CRLF Next ConsoleWrite($s_toconsole) EndFunc AutID 1 Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
mikell Posted November 23, 2014 Share Posted November 23, 2014 Nice effort Anyhow this kind of analysis code needs some prerequisites and error checking to be done before using it AutID If parentheses are missing or untidy then the code should work anyway and apply operators precedence but with obviously a less accurate breakdown Proper parentheses => accurate breakdown $eq = "(8 + (7 * 4)) - (3 - ((9 * 3) *(2 / (7 * 7))))" Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now