Announcement

Collapse
No announcement yet.

Code Golf: Evaluating Mathematical Expressions

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Code Golf: Evaluating Mathematical Expressions

    A challenge on stackoverflow.com is to come up with a function that uses the smallest amount of code (not compiled size) required to evaluate a simple mathematical expression. It's interesting to see the responses in various languages, and I was wondering how small PB can go. Many of the smallest solutions use regular expressions, but I decided not to mess with that for now.

    If you're interested, here's the thread/rules:
    Code Golf: Evaluating Mathematical Expressions.
    Write a function that takes a single argument that is a string representation of a simple mathematical expression and evaluates it as a floating point value. A "simple expression" may include any of the following: positive or negative decimal numbers, +, -, *, /, (, ). Expressions use (normal) infix notation. Operators should be evaluated in the order they appear, i.e. not as in BODMAS, though brackets should be correctly observed, of course. The function should return the correct result for any possible expression of this form. However, the function does not have to handle malformed expressions (i.e. ones with bad syntax).

    Examples of expressions:
    Code:
    1 + 3 / -8                            = -0.5       (No BODMAS)
    2*3*4*5+99                            = 219
    4 * (9 - 4) / (2 * 6 - 2) + 8         = 10
    1 + ((123 * 3 - 69) / 100)            = 4
    2.45/8.5*9.27+(5*0.0023)              = 2.68...
    And here's the code I came up with. It's a bit ugly, but the goal is to be small. I know I can make it even smaller, but haven't put much time into it.
    Code:
    #COMPILE EXE
    
    FUNCTION PBMAIN () AS LONG
        ? STR$(E("1 + 3 / -8"))
        ? STR$(E("2*3*4*5+99"))
        ? STR$(E("4 * (9 - 4) / (2 * 6 - 2) + 8"))
        ? STR$(E("1 + ((123 * 3 - 69) / 100)"))
        ? STR$(E("2.45/8.5*9.27+(5*0.0023)"))
    END FUNCTION  
    
    DEFDBL E,f,i,z,q,a,v,o  
    DEFSTR s,c,k,p
    
    FUNCTION E(s)  
    
        i=LEN(s)  
        DO  
            IF MID$(s,i,1)="("THEN  
                q=INSTR(i,s,")")  
                s=LEFT$(s,i-1)+STR$(E(MID$(s,i+1,q-i-1)))+MID$(s,q+1)  
            END IF  
            i-=1  
        LOOP UNTIL i=0  
    
        k="+-*/"  
        DIM p(PARSECOUNT(s,ANY k))  
        PARSE s,p(),ANY k  
    
        a=VAL(p(0))
    
        FOR i=1TO LEN(s)
            c=MID$(s,i,1)
            q=INSTR(k,c)
            IF q THEN
                z+=1
                IF o=0 THEN o=q ELSE p(z)=c+p(z)
                IF TRIM$(p(z))<>"" THEN
                    v=VAL(p(z))
                    a=CHOOSE(o,a+v,a-v,a*v,a/v)
                    o=0
                END IF
            END IF
        NEXT
    
        E=a  
    END FUNCTION
    Any challengers?
    Last edited by Bud Meyer; 6 Jun 2009, 04:59 PM. Reason: corrected first example expression
Working...
X