P is for Practical 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
```#!/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 "\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
Replies are listed 'Best First'.
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.

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 rifling through the Monastery: (13)
As of 2015-11-26 10:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?