Solve an algebraic expression

-5

The Challenge

Your task is to create a program that can solve an algebraic equation.

Input

Input will consist of a String. The string will be an equality involving the variable x, and follows the following rules:

  • the equation will always be linear
  • The valid operations in the equation are + - * /
  • Parenthesis will not be used
  • Order of operations must be respected
  • The coefficients of x will always have * in between the coefficient and x
  • You can assume that there will be exactly one solution for x

Output

Output will be through the stdout (or an acceptable equivalent). The output should be the value of x that satisfies the equality. (You can round to the nearest thousandth if the decimal expansion is too long.)


Test cases

x=5
=> 5

2*x=5
=> 2.5

3*x/2=7
=> 4.667

2*x=x+5
=> 5

3*x+3=4*x-1
=> 4

3+x*2+x=x+x/2+x/2
=> -3

Scoring

Because this is a , the shortest solution (in bytes) wins. (NOTE: You may not use built-ins that trivialize the problem.)

AMACB

Posted 2016-03-08T01:17:20.583

Reputation: 657

5You should avoid edits which disqualify existing answers. – Mego – 2016-03-08T02:03:43.390

6

In general we recommend challenges be posted to the Sandbox where they can get feedback from the community prior to being posted live.

– Alex A. – 2016-03-08T02:06:41.633

3please don't use built-ins is neither here or there. Are they allowed or are they not? And what built-ins does this cover? – Dennis – 2016-03-08T02:19:28.320

What do you mean "is neither here or there"? And no, they are not allowed if they trivialize the problem (e.g. you can do something like print solveThisEquation('x+4=5') – AMACB – 2016-03-08T02:27:05.067

3>

  • please don't use built-ins is a request, not a rule. 2. What about built-ins that parse the equation but do not solve it? Can we use eval?
  • < – Dennis – 2016-03-08T02:31:05.540

    >

  • Yes, it is a request. But that doesn't change anything. 2. You can't use a built-in algebraic solver, such as Mathematica's Solve.
  • < – AMACB – 2016-03-08T03:05:05.390

    3For the sake of clarity, we consider "request" and "rule" to be mutually exclusive. Challenge specifications should consist entirely of rules, e.g. "you must do this" or "you can't do that," rather than requests. Then it's not clear whether we actually can't do something. Do you see what I mean? – Alex A. – 2016-03-08T04:45:45.547

    Can there by signs on the numbers ? E.g. +5 + -3 * x – Ton Hospel – 2016-03-08T13:06:58.277

    Can I assume the multiplier will always be before the variable (eg x*3 never occurs)? – CalculatorFeline – 2016-03-08T15:16:58.220

    @AlexA. Then it is a rule. – AMACB – 2016-03-08T15:32:51.833

    Answers

    4

    Perl, 49 bytes

    Ah, builtins got disallowed. I'll leave this solution up for reference though it is now non competing.

    Includes +2 for -lp (-l can be dropped but is ugly)

    Run with the equation on STDIN:

    perl -lp algebra.pl <<< "x=5"
    

    algebra.pl:

    s'x'$.'g;$_=s/=(.*)/-($1)//(1-eval()*$.--/eval)
    

    Ton Hospel

    Posted 2016-03-08T01:17:20.583

    Reputation: 14 114

    1I can't tell whether this is symbolically solving the equation, but if it is then this is invalid as the OP has edited the question to disallow such built-ins. – Alex A. – 2016-03-08T02:05:33.770

    @AlexA. I don't think it is. – a spaghetto – 2016-03-08T02:16:50.037

    2@AlexA. No, it isn't symbolically solving. Perl has no "solve". It replaces f(x)=g(x) by f(x)-g(x), then uses a builtin to evaluates this at x=0 and x=1 respectively. It then calculates where the 0 must be – Ton Hospel – 2016-03-08T02:19:40.240

    2

    Javascript, 62 bytes

    Without builtins, but with eval.

    (s,f=eval("x=>"+s.replace(/=(.*)/,"-($1)")))=>f(0)/(f(0)-f(1))
    

    Uses eval to transform foo(x) = bar(x) into a function f(x) = foo(x) - bar(x), then calculates x = f(0) / (f(0) - f(1)).

    Rainer P.

    Posted 2016-03-08T01:17:20.583

    Reputation: 2 457

    Utterly explodes for input close() – CalculatorFeline – 2016-03-08T04:40:36.763

    2

    Python 3, 587 bytes

    from re import sub as r,findall as f
    a=input()
    i=int;s=str;l=len;d=r"(\d+\.?\d*)";d=d,d
    a=r(r"%s\*%s"%d,(lambda x:s(i(x.group(1))*i(x.group(2)))),a)
    a=r(r"%s\/%s"%d,(lambda x:s(i(x.group(1))/i(x.group(2)))),a)
    a=r(r"%s\-%s"%d,(lambda x:s(i(x.group(1))-i(x.group(2)))),a)
    a=r(r"%s\+%s"%d,(lambda x:s(i(x.group(1))+i(x.group(2)))),a)
    a=f(r"(\d+\.?\d*.)",a+"=")
    if l(a)==0 or a[0][1]!="*":a[0:0]=["1"]
    if l(a)==1 or a[1][1]!="=":a[1:1]=["0"]
    if l(a)==2 or a[2][1]!="*":a[2:2]=["1"]
    if l(a)==3 or a[3][1]!="=":a[3:3]=["0"]
    a=[int(x[0])for x in a]
    z=a[1]-a[3]
    print(z/(z-a[0]-a[1]+a[2]+a[3]))
    

    The only longer answers I've seen use 80% of the code to store a big data table. But unlike eval-based solutions, it only uses e twice! (In re and len.)

    Log, Day 20: Used Solve. Solve got banned. Learned re. Used re. Slept.

    CalculatorFeline

    Posted 2016-03-08T01:17:20.583

    Reputation: 2 608

    1

    Matlab, 61 bytes

    x=[1 0];a=eval([strrep(input(''),'=','-(') ')']);a(2)/diff(a)
    

    Uses the same algorithm as Ton Haspel to solve the equation. Replaces the = by -( and adds a ) at the end to make the string an equation that should equal zero, and solves (Newton's method is exact for linear functions).

    Input is just a string, e.g.: '3+x*2+x=x+x/2+x/2'.

    Matlab has a nice builtin for this too,

    solve(input(''))
    

    David

    Posted 2016-03-08T01:17:20.583

    Reputation: 1 316