| Blockland Forums > Modification Help |
| strMath() not working propperly |
| (1/2) > >> |
| Brian Smithers:
--- Code: ---function strMath(%str) { if(strLen(%str) <= 2) return; for(%i=0;%i<getWordCount(%str);%i++) { if(%i != 0 && %i != getWordCount(%str)) { %eq = getWord(%str,%i); echo(%eq); %n1 = %i - 1; %n1 = getWord(%str,%i); echo(%n1); %n2 = %i + 1; %n2 = getWord(%str,%i); echo(%n2); if(%n1 * 1 == %n1 && %n2 * 1 == %n2) { if(%eq $= "+" || %eq $= "-" || %eq $= "/" || %eq $= "*") %a += math(%n1,%n2,%eq); } } } return %a; } function math(%n1,%n2,%t) { switch$(%t) { case "+": return %n1 + %n2; case "-": return %n1 - %n2; case "/": return %n1 / %n2; case "*": return %n1 / %n2; default: return 0; } } --- End code --- This should beable to determine the equations output based off a string. When i put in echo(strMath("1 + 2")); it echo'd --- Quote from: console ---+ + + 2 2 2 0 --- End quote --- Anyone care to fix? Thanks |
| Port:
Sorry for spoon-feeding like this, but here I go. Supported operators: +, -, *, /, ^ and %. This can handle things such as: (5 ^ 3 % (17 + 4)) - 3 - 5 + 7 * (3 % 2) Even this: ( 5 ^ 3 % ( 17 + 4) ) - 3 -5 +7 *( 3 %2 ) --- Code: ---function strMath( %str ) { if ( !strLen( %str ) ) { return 0; } %off = 0; while ( true ) { %pos = striPos( %str, "(", %off ); if ( %pos < 0 ) { break; } %end = strPosBackwards( %str, ")", %pos ); if ( %end < 0 ) { continue; } %mat = trim( getSubStr( %str, %pos + 1, %end - ( %pos + 1 ) ) ); %str = setSubStr( %str, %pos, %end + 1, strMath( %mat ) ); %off = %end + 1; } %str = strReplace( %str, " ", "" ); %mat = "+-*/^%"; %off = 0; %val = 0; while ( true ) { %pos = strPosAny( %str, %mat, %off ); if ( %pos < 0 ) { break; } %prev = strPosAnyBackwards( %str, %mat, %pos ); %next = strPosAny( %str, %mat, %pos + 1 ); %type = getSubStr( %str, %pos, 1 ); if ( %prev < 0 && %next < 0 ) { %pre = getSubStr( %str, 0, %pos ); %sub = getSubStr( %str, %pos + 1, strLen( %str ) ); %prev = 0; %next = strLen( %str ) - 1; } else if ( %prev < 0 && %next >= 0 ) { %pre = getSubStr( %str, 0, %pos ); %sub = getSubStr( %str, %pos + 1, %next - ( %pos + 1 ) ); %prev = 0; %next = %next; } else if ( %prev >= 0 && %next < 0 ) { %pre = getSubStr( %str, %prev, %pos - %prev ); %sub = getSubStr( %str, %pos + 1, strLen( %str ) ); %prev = %prev + 1; %next = strLen( %str ) - 1; } else if ( %prev >= 0 && %next >= 0 ) { %pre = getSubStr( %str, %prev, %pos - %prev ); %sub = getSubStr( %str, %pos + 1, %next - ( %pos + 1 ) ); %prev = %prev + 1; %next = %next; } else { return 0; } if ( !strLen( %pre ) || !strLen( %sub ) ) { %str = setSubStr( %str, %prev, %next, 0 ); continue; } switch$ ( %type ) { case "+": %val = %pre + %sub; case "-": %val = %pre - %sub; case "*": %val = %pre * %sub; case "/": %val = %pre / %sub; case "^": %val = mPow( %pre, %sub ); case "%": %val = %pre % %sub; default: %str = setSubStr( %str, %prev, %next, 0 ); continue; } if ( %val $= "1.#INF" || %val $= "-1.#IND" ) { %val = 0; } %str = setSubStr( %str, %prev, %next, %val ); } return %val; } function setSubStr( %str, %start, %len, %val ) { return getSubStr( %str, 0, %start ) @ %val @ getSubStr( %str, %start + %len, strLen( %str ) ); } function strPosAny( %str, %list, %offset ) { if ( !strLen( %str ) || !strLen( %list ) ) { return -1; } if ( !strLen( %offset ) ) { %offset = 0; } %cnt = strLen( %str ); for ( %i = 0 ; %i < %cnt ; %i++ ) { if ( strPos( %list, getSubStr( %str, %i, 1 ) ) >= 0 ) { return %i; } } return -1; } function strPosBackwards( %str, %char, %offset ) { if ( !strLen( %str ) || !strLen( %char ) ) { return -1; } if ( !strLen( %offset ) ) { %offset = 0; } for ( %i = strLen( %str ) - 1 - %offset ; %i >= 0 ; %i-- ) { %chr = getSubStr( %str, %i, 1 ); if ( %chr $= %char ) { return %i; } } return -1; } function strPosAnyBackwards( %str, %list, %offset ) { if ( !strLen( %str ) || !strLen( %list ) ) { return -1; } if ( !strLen( %offset ) ) { %offset = 0; } for ( %i = strLen( %str ) - 1 - %offset ; %i >= 0 ; %i-- ) { %chr = getSubStr( %str, %i, 1 ); if ( strPos( %list, %chr ) >= 0 ) { return %i; } } return -1; } --- End code --- |
| Ipquarx:
I made a equation parser a while ago, using it for my chat mathbot ATM. It works perfectly, and works on bedmas, and is fairly compact and very fast. It auto-formats the equation to fit it, so as long as it's in a valid math format (number operator number) and all brackets have operators, like "5x(2+2)", it will work, no matter how badly spaced it is. It even does parenthesis's :D Here's the code: (edited to remove arbritrary-precision math functions i made) --- Code: ---function backwards(%a) { for(%b=0;%b<strLen(%a);%b+) %c = getSubStr(%a, %b, 1) @ %c; return %c; } function doEquation(%e) { %e = stripChars(%e, " "); %e = strReplace(%e, "+", " + "); %e = strReplace(%e, "x", " x "); %e = strReplace(%e, "/", " / "); %e = strReplace(%e, "-", " - "); %e = strReplace(%e, "^", " ^ "); if(strPos(%e, "(") > -1 && strPos(%e, ")") > 0) { %f = backwards(%e); %start = strPos(%e, "("); %close = mAbs(strPos(%f, ")") - strLen(%e)); %close2 = mAbs(%close - strLen(%e)); %e = doEquation(stripTrailingSpaces(getSubStr(%e, %start + 1, %close - 2))) @ getSubStr(%e, strLen(%e) - %close2, strLen(%e) - (strLen(%e) - %close2)); } for(%a=0;%a<getWordCount(%e);%a++) { if(getWord(%e, %a) $= "^" && %a != 0) { %f = getWord(%e, %a-1); %l = getWord(%e, %a+1); %e = setWord(%e, %a, mPow(%f, %l)); %e = removeWord(removeWord(%e, %a+1), %a-1); %a = %a - 2; } } for(%a=0;%a<getWordCount(%e);%a++) { if(getWord(%e, %a) $= "x" || getWord(%e, %a) $= "/" && %a != 0) { %f = getWord(%e, %a - 1); %l = getWord(%e, %a + 1); %o = getWord(%e, %a); switch$(%o) { case "x": %e = setWord(%e, %a, %f * %l); %e = removeWord(%e, %a + 1); %e = removeWord(%e, %a - 1); %a = %a - 2; case "/": %e = setWord(%e, %a, %f / %l); %e = removeWord(%e, %a + 1); %e = removeWord(%e, %a - 1); %a = %a - 2; } } } for(%a=0;%a<getWordCount(%e);%a++) { if(getWord(%e, %a) $= "+" || getWord(%e, %a) $= "-" && %a != 0) { %f = getWord(%e, %a - 1); %l = getWord(%e, %a + 1); %o = getWord(%e, %a); switch$(%o) { case "+": %e = setWord(%e, %a, %f + %l); %e = removeWord(%e, %a + 1); %e = removeWord(%e, %a - 1); %a = %a - 2; case "-": %e = setWord(%e, %a, %f - %l); %e = removeWord(%e, %a + 1); %e = removeWord(%e, %a - 1); %a = %a - 2; } } } return %e; } --- End code --- |
| Brian Smithers:
--- Quote from: Port on January 16, 2012, 03:32:45 AM ---Sorry for spoon-feeding like this, but here I go. Supported operators: +, -, *, /, ^ and %. This can handle things such as: (5 ^ 3 % (17 + 4)) - 3 - 5 + 7 * (3 % 2) Even this: ( 5 ^ 3 % ( 17 + 4) ) - 3 -5 +7 *( 3 %2 ) --- Code: ----snip- --- End code --- --- End quote --- Thanks :) --- Quote from: Ipquarx on January 16, 2012, 12:24:56 PM ---I made a equation parser a while ago, using it for my chat mathbot ATM. It works perfectly, and works on bedmas, and is fairly compact and very fast. It auto-formats the equation to fit it, so as long as it's in a valid math format (number operator number) and all brackets have operators, like "5x(2+2)", it will work, no matter how badly spaced it is. It even does parenthesis's :D Here's the code: (edited to remove arbritrary-precision math functions i made) --- Code: ----snip- --- End code --- --- End quote --- You too :) idk why you put in a backwards function though. |
| Ipquarx:
To find the last closing parenthesis. Trust me, it's a fully functional recursive-looping equation parser, and it's easy to add even more operators. It's fairly short compared to port's and as it looks, quite a bit more memory/processing-power efficiant. |
| Navigation |
| Message Index |
| Next page |