#!/usr/bin/perl
# http://perlmonks.org/?node_id=1125392
use strict;
my @stack;
$_ = @ARGV ? "@ARGV" : '2 4x*8-*3x*+11x*1+9--'; # x cancels out
$_ = @ARGV ? "@ARGV" : '2 4x*8-*3x*+10x*1+9--'; # adjusted
print " raw $_\n";
use Data::Dump qw(pp);
while( /(\d+)|(x)|([*+-])/g )
{
pp \@stack;
if( length $1 )
{
push @stack, [ $1 ];
}
elsif( $2 )
{
push @stack, [ 0, 1 ];
}
else
{
my $op = $3;
my ($x, $y) = splice @stack, -2;
if( $op eq '+' )
{
my $i = 0;
$x->[$i++] += $_ for @$y;
push @stack, $x;
}
elsif( $op eq '-' )
{
my $i = 0;
$x->[$i++] -= $_ for @$y;
push @stack, $x;
}
elsif( $op eq '*' )
{
push @stack, multiply( $x, $y );
}
}
}
pp \@stack;
my ($x0, $x1) = @{ pop @stack };
if( $x1 )
{
print "x = ", -$x0 / $x1, "\n";
}
else
{
die "x has cancelled out";
}
sub multiply # two polynomials
{
my ($x, $y) = @_;
my ($n, @result) = (0);
for my $xval (@$x)
{
my $pos = $n;
$result[$pos++] += $xval * $_ for @$y;
$n++;
}
return \@result;
}
|