in reply to Re: Reverse Polish Notation Question
in thread RPN Question

Two comments:

From $temp == $val, you cannot conclude that there is no solution, unless you explicitly assume that we have a linear equation, ie a straight line.

If you would calculate the slope from the first two values, you can guess quite well where the solution is, especially for a linear equation.

Replies are listed 'Best First'.
Re^3: Reverse Polish Notation Question
by Laurent_R (Canon) on May 02, 2015 at 14:48 UTC
    Thank you hdb for your comments.

    As for the first comment, we have a first degree equation, so, yes, I assumed a straight line on that specific condition, although I was more broadly trying to implement a more general solution.

    For your second comment, yes, you are absolutely right, calculating the slope would far easier, especially for a linear equation, and I would not even need to painfully consider whether the various calculated values are positive or negative. And even for a polynomial equation, say second or third degree, calculating the slope would narrow down faster on the solution (something similar to the Newton-Raphson method).

    My error was to initially think it could be done in 15 minutes and 20 lines of code, so I started to code something without carefully thinking of the problem, and discovered only when doing it that it was more complicated than I thought. If I have time this weekend, I'll try to come up with a better design.

    Je suis Charlie.

      For a linear equation it could look like this (and yes, it took me more than 15 minutes...)

      use strict; use warnings; my $equation = "(2*(4*x-8)+3*x)-(10*x+1-9)"; # " = 0" omitted $equation =~ s/x/\$_[0]/g; my $eval = sub { eval $equation }; my $val1 = $eval->(0); my $val2 = $eval->(1); die "No solution for this equation\n" unless $val1 - $val2; my $result = -$val1 / ($val2 - $val1); printf "Result is %.10f\n", $result;
        I tried to time your version and mine (removing the printouts). As I would expect yours is faster, but mine is converging fast enough to make the difference very small:

        Your solution:

        $ time perl -e 'use strict; > use warnings; > my $val2 > = $eval->(1); my $equation = "(2*(4*x-8)+3*x)-(10*x+1-9)"; # " = 0" omitted > $equation =~ s/x/\$_[0]/g; > my $eval = sub { eval $equation }; > my $val1 = $eval->(0); > my $val2 = $eval->(1); > die "No solution for this equation\n" unless $val1 - $val2; > my $result = -$val1 / ($val2 - $val1); > > printf "Result is %.10f\n", $result;' Result is 8.0000000000 real 0m0.044s user 0m0.015s sys 0m0.031s
        and mine:
        $ time perl solver.pl Result is: 8.0000000000 real 0m0.050s user 0m0.031s sys 0m0.015s
        0.44 versus 0.50 sec. I might have been lucky on this one, but, frankly, my narrowing-down algorithm works fairly well.

        Je suis Charlie.
        Hi hdb, that's a pretty neat solution.

        It took me twenty seconds or so to figure out why you were replacing x by $_[0]. I must say that this is a nice clever idea.

        Je suis Charlie.