Although this is not really what you are asking for, another approach for such equation solving, frequently employed in math libraries, is to guess a value and make successive improvements to get closer and closer approximations of the target number.

I thought that it would take me 15 minutes to show an example, but it turned out that it took me an hour and a half, because of some initial mistakes on my part due to the fact that I was not entirely clear in my mind on what exactly I needed to do.

It could probably be simpler, this is very imperfect and not tested against all kinds of cases, but anyway, this gives an idea of the approach:

use strict; use warnings; use feature "say"; use constant DEBUG => 1; my $epsilon = 1e-12; # precision my ($result, $step) = (0, 10); # arbitrary start values my $equation = "(2*(4*x-8)+3*x)-(10*x+1-9)"; # " = 0" omitted $equation =~ s/x/\$x/g; my $eval = create_eval($equation); # currying the equation for simplic +ity my $debug = 1; while (1) { my $val = $eval->($result); last if abs $val < $epsilon; my $new_result = $result + $step; my $temp = $eval->($new_result); say "x = $result ; val = $val ; temp = $temp; step = $step" if DEB +UG; $result = $new_result and last if abs $temp < $epsilon; if ($temp == $val) { say "No solution for this equation"; undef $result; last; } if (($val > 0 and $temp < 0) or ($val < 0 and $temp > 0)) { while (1) { $step = 0; my $avg = ($result + $new_result) /2; my $avg_val = $eval->($avg); # say "x = $result; val = $val ; temp = $temp; step = $ste +p; avg = $avg" if DEBUG; printf "%s%.15f%s%.15f%s%.15f%s%.15f\n", "x = ", $result, +" val = ", $val, " temp = ", $temp, " avg = ", $avg; $new_result = $avg and last if abs $avg_val < $epsilon; if ($avg_val > 0) { $result = $avg and $val= $avg_val if $val > 0; $new_result = $avg and $temp = $avg_val if $temp > 0; } else { $result = $avg and $val = $avg_val if $val < 0; $new_result = $avg and $temp = $avg_val if $temp < 0; } } } $step = -$step and next if $temp < $val and $val < 0; $step /= 2 and next if abs $temp > abs $val; # we are further + from 0, reduce step by half $result =$new_result; # $temp is closer to 0, let's continue +with $new_resultp } printf "%s%.10f\n", "Result is: ", $result;# if defined $result; sub create_eval { my $formula = shift; return sub { my $x = shift; return eval($formula);} }
The result I get is 8.00000..., so the same as the RPN unraveling by Anonymous Monk, except of course that I do not get an integer but a floating point number.

Just to see the successive approximations, this is the debugging printout.

$ perl solver.pl x = 0 ; val = -8 ; temp = 2; step = 10 x = 0.000000000000000 val = -8.000000000000000 temp = 2.00000000000000 +0 avg = 5.000000000000000 x = 5.000000000000000 val = -3.000000000000000 temp = 2.00000000000000 +0 avg = 7.500000000000000 x = 7.500000000000000 val = -0.500000000000000 temp = 2.00000000000000 +0 avg = 8.750000000000000 x = 7.500000000000000 val = -0.500000000000000 temp = 0.75000000000000 +0 avg = 8.125000000000000 x = 7.500000000000000 val = -0.500000000000000 temp = 0.12500000000000 +0 avg = 7.812500000000000 x = 7.812500000000000 val = -0.187500000000000 temp = 0.12500000000000 +0 avg = 7.968750000000000 x = 7.968750000000000 val = -0.031250000000000 temp = 0.12500000000000 +0 avg = 8.046875000000000 x = 7.968750000000000 val = -0.031250000000000 temp = 0.04687500000000 +0 avg = 8.007812500000000 x = 7.968750000000000 val = -0.031250000000000 temp = 0.00781250000000 +0 avg = 7.988281250000000 x = 7.988281250000000 val = -0.011718750000000 temp = 0.00781250000000 +0 avg = 7.998046875000000 x = 7.998046875000000 val = -0.001953125000000 temp = 0.00781250000000 +0 avg = 8.002929687500000 x = 7.998046875000000 val = -0.001953125000000 temp = 0.00292968750000 +0 avg = 8.000488281250000 x = 7.998046875000000 val = -0.001953125000000 temp = 0.00048828125000 +0 avg = 7.999267578125000 x = 7.999267578125000 val = -0.000732421875000 temp = 0.00048828125000 +0 avg = 7.999877929687500 x = 7.999877929687500 val = -0.000122070312500 temp = 0.00048828125000 +0 avg = 8.000183105468750 x = 7.999877929687500 val = -0.000122070312500 temp = 0.00018310546875 +0 avg = 8.000030517578125 x = 7.999877929687500 val = -0.000122070312500 temp = 0.00003051757812 +5 avg = 7.999954223632812 x = 7.999954223632812 val = -0.000045776367188 temp = 0.00003051757812 +5 avg = 7.999992370605469 x = 7.999992370605469 val = -0.000007629394531 temp = 0.00003051757812 +5 avg = 8.000011444091797 x = 7.999992370605469 val = -0.000007629394531 temp = 0.00001144409179 +7 avg = 8.000001907348633 x = 7.999992370605469 val = -0.000007629394531 temp = 0.00000190734863 +3 avg = 7.999997138977051 x = 7.999997138977051 val = -0.000002861022949 temp = 0.00000190734863 +3 avg = 7.999999523162842 x = 7.999999523162842 val = -0.000000476837158 temp = 0.00000190734863 +3 avg = 8.000000715255737 x = 7.999999523162842 val = -0.000000476837158 temp = 0.00000071525573 +7 avg = 8.000000119209290 x = 7.999999523162842 val = -0.000000476837158 temp = 0.00000011920929 +0 avg = 7.999999821186066 x = 7.999999821186066 val = -0.000000178813934 temp = 0.00000011920929 +0 avg = 7.999999970197678 x = 7.999999970197678 val = -0.000000029802322 temp = 0.00000011920929 +0 avg = 8.000000044703484 x = 7.999999970197678 val = -0.000000029802322 temp = 0.00000004470348 +4 avg = 8.000000007450581 x = 7.999999970197678 val = -0.000000029802322 temp = 0.00000000745058 +1 avg = 7.999999988824129 x = 7.999999988824129 val = -0.000000011175871 temp = 0.00000000745058 +1 avg = 7.999999998137355 x = 7.999999998137355 val = -0.000000001862645 temp = 0.00000000745058 +1 avg = 8.000000002793968 x = 7.999999998137355 val = -0.000000001862645 temp = 0.00000000279396 +8 avg = 8.000000000465661 x = 7.999999998137355 val = -0.000000001862645 temp = 0.00000000046566 +1 avg = 7.999999999301508 x = 7.999999999301508 val = -0.000000000698492 temp = 0.00000000046566 +1 avg = 7.999999999883585 x = 7.999999999883585 val = -0.000000000116415 temp = 0.00000000046566 +1 avg = 8.000000000174623 x = 7.999999999883585 val = -0.000000000116415 temp = 0.00000000017462 +3 avg = 8.000000000029104 x = 7.999999999883585 val = -0.000000000116415 temp = 0.00000000002910 +4 avg = 7.999999999956344 x = 7.999999999956344 val = -0.000000000043656 temp = 0.00000000002910 +4 avg = 7.999999999992724 x = 7.999999999992724 val = -0.000000000007276 temp = 0.00000000002910 +4 avg = 8.000000000010914 x = 7.999999999992724 val = -0.000000000007276 temp = 0.00000000001091 +4 avg = 8.000000000001819 x = 7.999999999992724 val = -0.000000000007276 temp = 0.00000000000181 +9 avg = 7.999999999997272 x = 7.999999999997272 val = -0.000000000002728 temp = 0.00000000000181 +9 avg = 7.999999999999545 Result is: 8.0000000000

Je suis Charlie.

In reply to Re: Reverse Polish Notation Question by Laurent_R
in thread RPN Question by nat47

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.