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

Go to full version