# Evaluate polynomial expression string

Create a function which takes a polynomial equation, a value for x and returns the result of the operation.

Example: given 4x^2+2x-5 and x=3 output 37. This is the result of 4(3)^2+2(3)-5

• Assume all polynomials are valid
• Polynomial format will always be coefficient(variable)^exponent => 4x^2 except :
• When exponent is 1 it will be coefficient(variable) => 4x
• When coefficient is 1 it will be (variable)^exponent => x^2
• Polynomials are one variable only
• Use of external libraries are forbidden
• The coefficient and variable input can be positive and negative numbers.

Test cases

• ("3x^3-5x^2+2x-10", 5) => 250
• ("10x^4-5x^3-10x^2+3x+50", 3) => 644
• ("10x+20", 10) => 120
• ("-20x^2+20x-50", -8) => -1490
• ("9", 5) => 9
• ("8x^2+5", 0) => 5

Update

• Polynomial format will always be coefficient(variable)^exponent => 4x^2 except :
• When exponent is 1 it will be coefficient(variable) => 4x
• When coefficient is 1 it will be (variable)^exponent => x^2
• Removed the rule of negative exponent. My mistake. A valid polynomial does not contain negative exponent
• An exponent of 0 would be just coefficient
• Added test case for input 0

This is , so the shortest answer in bytes win.

• How flexible is the input format? Instead of 3x^3-5x^2+2x-10 can we input 3*x^3-5*x^2+2*x-10? Or [3 -5 2 -10]. [3 2 1 0]? Jun 4, 2018 at 13:59
• @Arnauld Yes... Jun 4, 2018 at 20:04
• What is an "external library" and how is it fair, compared to languages who have "eval" already implemented as a feature? Jun 4, 2018 at 23:02
• My apologies I haven't use my pc since yesterday. I have updated the challenge with the suggestions you gave me. Please take a look at it and reopen it if everything is ok. Jun 5, 2018 at 12:32
• Please merge the "Update" part. Jun 5, 2018 at 13:39

# JavaScript (ES7), 48 bytes

Based upon a suggestion from @RickHitchcock

Expects X in uppercase. Takes input in currying syntax (p)(X).

p=>X=>eval(p.replace(/[X^]/g,c=>c<{}?'*X':'**'))


Try it online!

# JavaScript (ES7), 49 bytes

Same approach as @DeadPossum. Takes input in currying syntax (p)(x).

p=>x=>eval(p.splitx.join*x.split^.join**)


Try it online!

• I think you can save a couple bytes by using replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**')) Jun 4, 2018 at 19:50
• @RickHitchcock I can't use a reference to f unless it's included in the byte count, at the cost of the 2 bytes that are supposed to be saved. I like this method, though. There might be a way to save a byte or two by revamping it somehow. Jun 4, 2018 at 20:00
• @RickHitchcock If we can take X in uppercase, then we can do a<{}?'*X':'**', saving a byte. Hence my question to the OP. Jun 4, 2018 at 20:03
• cant handle x alone
– l4m2
Jun 7, 2018 at 9:01
• @l4m2 The challenge rules were updated. :/ It used to be 1x for x. Jun 7, 2018 at 9:08

# Python 2, 54 bytes

-2 bytes thanks to Jo King

-5 bytes thanks to Arnauld

lambda p,x:eval(p.replace('^','**').replace('x','*x'))


Try it online!

# Python 3, 5350 48 bytes

edit: -5 bytes thanks to Dennis !

lambda p,x:eval(p.translate({94:"**",120:"*x"}))


Try it online!

Used translate to avoid chaining replace calls; Python 3's version of translate is less awkward than its predecessor's.

• "*(%d)"%x can become "*(x)". Jun 4, 2018 at 14:11
• Thank you, I hadn't event figured out x was in my eval scope ! I'll update. Jun 4, 2018 at 15:36
• Actually, since x is no longer a string representation, "*x" works as well. Jun 4, 2018 at 15:56
• Even better ! Thanks again. Jun 4, 2018 at 18:00

# R, 44 bytes

function(f,x)eval(parse(t=gsub("x","*x",f)))


Try it online!

Fairly straightforward with R. Replace nx with n*x and then eval the parsed string. x is used as this is how we name the second argument.

The eval function could even be used more directly with a properly formatted first argument, and other formal arguments (y, z, etc.) could be easily added:

### R, 20 bytes (non-competing)

function(f,x)eval(f)


Try it online!

# Japt 2.0, 13 bytes

OvUd^'*²'x"*V


## Explanation:

OvUd^'*²'x"*V
U = Implicit first input
V = Implicit second input

Ov            Eval:
Ud            In U, replace:
^             "^" with:
'*²            "**"
'x        "x" with:
"*V       "*V"


# Wolfram Language (Mathematica), 22 bytes

ToExpression@#/.x->#2&


Try it online!

# JavaScript (Node.js), 113 108 bytes

_=>x=>_.match(/-?(?:[x\d]+|\^?)+/g).reduce((a,b)=>b.splitx*(~b.indexOfx?x**(b.split^||1):1)+a,0)


Try it online!

Thanks to @Arnauld

Since the best JS solution so far by @Arnauld (49 bytes) has already been posted and it uses eval, I decided to use Regex and reduce instead of that.

Pretty lengthy compared to his though.

# Explanation :

A =>                            // lambda function accepting argument 1
x =>                        // argument number 2 (currying syntax used)
A.match(                // this matches all instance of what comes next
// and converts to array
/[-]?(?:[x\d]+|\^?)+/g)  // regexp for -ve sign , variable number and ^ sign
.reduce((a, b) =>   // reduce the array to single (take 2 params a,b)
b.split x     // split b at instances of x
     // and select the first instance
* (b.indexOfx // multiply that by value of index of x in b
> 0 ?       // if it is greater than 0 then
x **            // multiplication will be with x raised to power
(l = b.split ^ // set variable split b at every x
||1       // choose first index otherwise set to one
)               // this is what x is raised to the power
: 1)            // in the case x is not present multiply by 1
+ a,            //  add value of a to that value
0)                      // in case no reduce is possible set value to 0


• This currently fails on the last test case (should be 0.25). You can save a few bytes by using - instead of [-], ~b.indexOfx  instead of b.indexOfx>0 and removing l= which is not used. (But this doesn't fix the bug.) Jun 4, 2018 at 20:39
• @Arnauld: Thanks. No idea why it does that, will see what the problem Jun 4, 2018 at 20:59
• Well, the problem is that your regex splits 1x^-2 on the -. Jun 4, 2018 at 21:03

# 05AB1E, 16 19 bytes

„*(I')J'xs:'^„**:.E


+3 bytes as bug-fix for negative input x.

.E (Run as Batch code) has been replaced with Run as Python eval in this latest commit of @Adnan, but this version isn't on TIO yet. @Mr.Xcoder tested it on his local (latest version) 05AB1E to verify it's working.
See this version without .E to see how it converted the expression string.

Explanation:

„*I')J'xs:    # Replace all "x" with "*(n)" (where n is the input-integer)
#  i.e. 5 and 3x^3-5x^2+2x-10 → 3*(5)^3-5*(5)^2-2*(5)-10
'^„**:        # Replace all "^" with "**"
#  i.e. 3*(5)^3-5*(5)^2-2*(5)-10 → 3*(5)**3-5*(5)**2-2*(5)-10
.E            # Evaluate as Python-eval
#  i.e. 3*(5)**3-5*(5)**2-2*(5)-10 → 250


Alternative 25 28 bytes program that works on the current version of TIO:

„*(I')J'xs:'^„**:“…¢(“s')J.e


Try it online.

Explanation:

„*(I')J'xs:'^„**:    # Same as explained above
“…¢(“                # Literal string "print("
s               # Swap both
')             # Literal character ")"
J            # Join everything together
#  i.e. 3*(5)**3-5*(5)**2-2*(5)-10 → print(3*(5)**3-5*(5)**2-2*(5)-10)
.e                   # Run as Python code
#  i.e. print(3*(5)**3-5*(5)**2-2*(5)-10) → 250


“…¢(“ is the string print(, because:

• “ and “ starts and ends the compressed string
• …¢ is equal to 0426 because it looks at the indices in the info.txt file, where … has index 4, and ¢ has index 26.
• This index 0426 is then used in the dictionary-file, where line 427 (index 426) is the word it fetches, which is print in this case.
• The ( doesn't have an index in the info.txt file, so it is interpret as is.

# TI-Basic, 6 bytes

Prompt X:expr(Ans


Expression is taken as argument and X is entered during runtime. Alternatively 8 bytes without expr:

Prompt X,u:u


Here both arguments are entered at runtime.

# JavaScript (Node.js), 143 bytes

I know there are better answers but I wanted to do it without using eval

(_,x)=>_.match(/[+-]?(?:[a-z0-9.]+|\^-?)+/gi).reduce((a,b)=>~~(b.split('x'))*(b.indexOf('x')>0?Math.pow(x,(l=(b.split('^')))?l:1):1)+a,0)


Try it online!

• Your regex doesn't need [a-z0-9.] does it? The only letter that can appear is x. Any why .? You don't need to handle non-integer coefficients or exponents. Jun 5, 2018 at 4:58

# Physica, 35 bytes

->e;x:Eval@Replace[e;"x";f"*({x})"]


Try it online!

# Jelly, 21 bytes

ṣ”^j⁾**ṣ”xjØ(j”*;Ʋ}ŒV


Try it online!

• Due to operator precedence, this doesn't work for ("-20x^2+20x-50", -8). Jun 4, 2018 at 18:15
• @Dennis Adjusted accordingly. Jun 4, 2018 at 18:51

# Java 8, 150149 148 bytes

n->s->new javax.script.ScriptEngineManager().getEngineByName("JS").eval(s.replace("x","*"+n).replaceAll((s="(\\-?\\d+)")+"\\^"+s,"Math.pow($1,$2)"))


Not sure if it's possible to have a currying lambda function that throws an Exception. If it is, 1 byte can be saved changing (s,n)-> to n->s->. -1 byte thanks to @OlivierGrégoire for showing me how to do this.

Try it online.

Explanation:

n->s->     // Method with integer and String parameters and Object return-type
new javax.script.ScriptEngineManager().getEngineByName("JS")
//  Use a JavaScript engine
.eval(s  //  And eval the input
.replace("x","*"+n)
//   After all 'x' has been replaced with '*n'
//   (where n is the input-integer)
.replaceAll((s="(\\-?\\d+)")+"\\^"+s,"Math.pow($1,$2)"))
//   And all A^B have have been replaced with Math.pow(A,B)
//   (where both A and B are integers)


Unfortunately the JavaScript eval doesn't support **, so I have to use a longer replace to convert it to Math.pow instead..

• JavaScript does support ** (ES7+), why does this not support that ? Jun 4, 2018 at 14:16
• Also is there no eval in java. That can't be right ? Jun 4, 2018 at 14:17
• @MuhammadSalman Nope, Java has no eval. And I think this builtin JavaScript-eval I can use with ScriptEngineManager hasn't been updated in the Java JDK for years, so it doesn't support ES7+.. Jun 4, 2018 at 14:20
• Man, java sucks, no eval why ? Okay why hasn't it been updated ? Jun 4, 2018 at 14:21
• Jun 4, 2018 at 22:54

# Ruby, 43 41 bytes

->p,x{eval p.gsub('^','**').gsub'x','*x'}


Try it online!

Saved two bytes thanks to @Mr.Xcoder

Since there isn't a Ruby answer yet I added one. Nvm there was one that used a different approach

# Explanation :

->p,x{                    # lambda function that takes two arguments p and x
eval(                 # eval
p.gsub(           # replace all instance of
'^' , '**'    # ^ with ** (use for raised to power of)
)                 # end gsub
.gsub(            # start another replace all
'x' , '*x'    # replace all instances of x with *x
)                 # end the replace function
)                     # end eval function
}                         # end lambda function


# Excel, 36+2 bytes, Non-competing

Evaluating a Text field as a formula is not straight forward in Excel. There is a hidden =EVALUATE() function, that can be called by defining a Name.

In Excel 2007, Formulas > Define Name. Define a Name called E, with Refers to:

=EVALUATE(SUBSTITUTE(A1,"x","*"&B1))


Then, with Formula input in A1, x value in B1, entering =E in C1 returns expected result.

# Octave, 4738 37 bytes

Saved a lot of bytes by taking the second input as a string instead of a number.

@(x,c)eval(strrep(x,'x',['*(',c,41]))


Try it online!

### Explanation:

Fairly straight forward: Replace x by (c) , where c is the second input, and evaluate. The paretheses are necessary because in Octave -8^2 == -64.

# Ruby, 43 bytes

->s,x{eval s.gsub /[x^]/,?x=>"*x",?^=>"**"}


Try it online!

• Nice approach with hash replacement, but straight two gsubs are even shorter Jun 4, 2018 at 13:34

# Perl 5-pl, 35 bytes

s/\^/**/g;$q=<>;s/x/*($q)/g;\$_=eval


Try it online!

# Wolfram Language (Mathematica), 19 bytes

(x=#;ToExpression)&


Try it online!

Take input by currying: f[x][expr].