Thanks! That's awesome. I don't need all those little variables and perl eval()s for me! Great!
-Variable_B | [reply] |
Glad you liked it. As we all know, Laziness is a wonderful virtue. But I figured I should provide you with something more constructive. Here are the basics of that reverse Polish calculator I was rambling about. It supports +, -, *, /. Print the stack with 'p' and quit with 'q'. You could probably make this a bit more concise if you wanted to. In fact, that might make for some pretty good GOLF. Anyway, Enjoy.
#!/usr/bin/perl -w
use strict;
my @stack = ();
my %ops = ( '+' => \&sum, '-' => \&difference,
'*' => \&product, '/' => \"ient,
'p' => sub { print $_, "\n" foreach @stack; },
'q' => sub { exit 0; }
);
while(<>) {
chomp;
if (exists $ops{$_}) {
$ops{$_}->();
# The badass regex is out of the Perl Cookbook, page 44
# Makes sure non-ops are valid numbers
} elsif ($_ =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) {
push @stack, $_;
} else {
warn "Bad input: $_\n";
}
}
sub pop_stack {
my $rhs = pop @stack;
my $lhs = pop @stack;
if ((! defined $lhs) || (! defined $rhs)) {
warn "Not enough values on stack!\n";
push @stack, $rhs if defined $rhs;
return undef;
}
return $lhs, $rhs;
}
sub sum {
my ($lhs, $rhs) = pop_stack;
return unless defined $lhs;
my $res = $lhs + $rhs;
print "$res \n";
push @stack, $res;
}
sub difference {
my ($lhs, $rhs) = pop_stack;
return unless defined $lhs;
my $res = $lhs - $rhs;
print "$res \n";
push @stack, $res;
}
sub product {
my ($lhs, $rhs) = pop_stack;
return unless defined $lhs;
my $res = $lhs * $rhs;
print "$res \n";
push @stack, $res;
}
sub quotient {
my ($lhs, $rhs) = pop_stack;
return unless defined $lhs;
my $res = $lhs / $rhs;
print "$res \n";
push @stack, $res;
}
| [reply] [d/l] |
Well, here's a little bit of golf right off the bat. Since we are checking the input, we can get away with an eval without fear:
#!/usr/bin/perl -w
use strict;
my @stack = ();
my %ops = ( '+' => \&calc, '-' => \&calc,
'*' => \&calc, '/' => \&calc,
'p' => sub { print $_, "\n" foreach @stack; },
'q' => sub { exit 0; }
);
while(<>) {
chomp;
if (exists $ops{$_}) {
$ops{$_}->($_);
# The badass regex is out of the Perl Cookbook, page 44
} elsif ($_ =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) {
push @stack, $_;
} else {
warn "Bad input: $_\n";
}
}
sub calc {
my $op = shift;
my $rhs = pop @stack;
my $lhs = pop @stack;
if ((! defined $lhs) || (! defined $rhs)) {
warn "Not enough values on stack!\n";
push @stack, $rhs if defined $rhs;
return undef;
}
my $res = eval $lhs.$op.$rhs;
print "$res\n";
push @stack, $res;
}
Fix: I had the rhs and lhs backwards in the eval originally | [reply] [d/l] |
That is far above me but I will get there.
-Variable_B
| [reply] |
That's above me but I am getting there!
-Variable_B
| [reply] |
| [reply] |