For the =, move it to the opposite side of the = by changing its sign and drop the =. Then everything is on one side, and the other side (no longer needed) is 0. (see one of the tweaks: s/(.*)=(.*)/($1)-($2)/; )

Normally I'd use Parse::Yapp for the parsing, but you said no modules. (I just use Data::Dump for debugging.)

#!/usr/bin/perl # http://perlmonks.org/?node_id=1124684 use strict; # hand rolled recursive descent parser using /\G/gc use Data::Dump qw(pp); # anon arrays are [x^0, x^1, x^2, ...] my $variable; @ARGV or @ARGV = split /\n/, <<END; 10x+4=7 3(x+9)=8x 3(x-1)=2x-1 oops = 42 ++ 23 (x-1)(x+1) = 0 2+3x+7(x+27)-6= 23x-45-(145+62-5)x END for ( @ARGV ) { eval # for the die's { $variable = undef; print "\n"; print " raw input: $_\n"; s/\d\K(?=[a-zA-Z])/*/g; # insert missing ops for consistent parse s/(.*)=(.*)/($1)-($2)/; s/ \w+\K (?=\() | \)\K (?=\w) | \)\K (?=\() /*/gx; print "tweaked input: $_\n"; # added default operators my $answer = expr(); /\G\s*\z/gc or error(); # verify complete parse pp "raw answer for $variable ", $answer; defined $variable or die "no variable given"; pop @$answer while @$answer > 2 && $answer->[-1] == 0; # trim trai +ling 0's $answer->[1] or die "variable $variable cancels out"; @$answer > 2 and die "quadratic or higher equation"; print "\n $variable = ", -$answer->[0] / $answer->[1], "\n"; }; $@ and print $@; } sub expr # left associative => term ([+-] term)* { my $left = term(); while( /\G\s*((\+)|-)/gc ) { my $add = $2; my $right = term(); if($add) { $left->[$_] += $right->[$_] for 0..$#$right; } else { $left->[$_] -= $right->[$_] for 0..$#$right; } } return $left; } sub term # left associative => factor (* factor)* { my $left = item(); while( /\G\s*\*/gc ) { my $right = item(); my @result = (0) x (@$left + @$right - 1); my $n = 0; for my $vl (@$left) # cross multiply { my $pos = $n; $result[$pos++] += $vl * $_ for @$right; $n++; } pop @result while @result > 2 && $result[-1] == 0; # trim trailing + 0's $left = [ @result ]; } return $left; } sub item # parens or number or variable or unary minus { if( /\G\s*\(/gc ) { my $val = expr(); return /\G\s*\)/gc ? $val : error(); # must have closing paren } /\G\s*((\d+(\.\d*)?|\.\d+))/gc and return [ $1, 0 ]; if( /\G\s*(\w+)/gc ) { defined $variable && $variable ne $1 and die "more than one variable used '$variable' and '$1'"; $variable = $1; return [ 0, 1 ]; } if( /\G\s*-/gc ) # unary minus { my $right = item(); return [ map -$_, @$right ]; } error(); } sub error { s/\G/ SYNTAX ERROR->/; die "$_\n"; }

In reply to Re: How would you solve a user-inputted simple one-variable Linear Equation by Anonymous Monk
in thread How would you solve a user-inputted simple one-variable Linear Equation 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.