Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: Perl and maths

by sleepingsquirrel (Hermit)
on Feb 15, 2005 at 18:00 UTC ( #431278=note: print w/ replies, xml ) Need Help??


in reply to Perl and maths

Here are the beginnings of a brief skeleton of an evaluator for simple (and fully parenthesized) arithmetic expressions to get you started. It prints out all of the intermediate steps before it gets to the final answer. You'd need to swizzle the results around to get exactly what you wanted, but I think you get the idea...

((1+2)+((3+4)+(5*6)))
1 + 2 = 3
3 + 4 = 7
5 * 6 = 30
7 + 30 = 37
3 + 37 = 40
Final Answer: 40
#!/usr/bin/perl -w # # Evaluate simplified arithmetic expressions # use re 'eval'; #use recursive regex for parsing use strict; our $num = qr{\d+}; our $op = qr{[+*/\-]}; # an expression is a number or a pair of expressions separated by # an operator, enclosed in parens. our $exp; $exp = qr{$num|\(\s*(??{$exp})\s*$op\s*(??{$exp})\s*\)}s; # Something to test the evaluator with my @tests = ("(1+2)","((3+4)+(5+6))","((1+2)+((3+4)+(5*6)))"); for my $t (@tests) { print "$t\n"; print "Final Answer: ", simplify($t); print "\n\n"; } sub simplify { my $e = shift; if($e =~ /^($num)$/s) { return $1; } elsif ($e =~ /^\(($exp)\+($exp)\)$/s) { my ($l, $r) = ($1,$2); my $left = simplify($l); my $right = simplify($r); my $sum = $left + $right; # You'll need to do more here if # you're doing fractions. print "$left + $right = $sum\n"; return "$sum"; } elsif ($e =~ /^\(($exp)-($exp)\)$/s) { #subtraction } elsif ($e =~ /^\(($exp)\*($exp)\)$/s) { my ($l, $r) = ($1,$2); my $left = simplify($l); my $right = simplify($r); my $prod = $left * $right; print "$left * $right = $prod\n"; return "$prod"; } elsif ($e =~ /^\(($exp)\/($exp)\)$/s) { #division } else { die "Syntax error\n"; } }


-- All code is 100% tested and functional unless otherwise noted.


Comment on Re: Perl and maths
Download Code
Re^2: Perl and maths
by sleepingsquirrel (Hermit) on Feb 15, 2005 at 19:43 UTC
    Here's a modification to my code above which handles adding fractions and printing out the partial results. Finishing it off is left as an exercise to the reader...
    (1/2+2/3)
    7/6

    (1/2+(2/3+4/5))
    (1/2+22/15)
    59/30

    ((5/3+7/13)+(5/2+3/7))
    (86/39+(5/2+3/7))
    (86/39+41/14)
    2803/546


    -- All code is 100% tested and functional unless otherwise noted.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://431278]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2014-09-23 04:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (210 votes), past polls