18
\$\begingroup\$

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.

\$\endgroup\$
11
  • 3
    \$\begingroup\$ 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]? \$\endgroup\$
    – Luis Mendo
    Jun 4, 2018 at 13:59
  • 1
    \$\begingroup\$ @Arnauld Yes... \$\endgroup\$ Jun 4, 2018 at 20:04
  • 4
    \$\begingroup\$ What is an "external library" and how is it fair, compared to languages who have "eval" already implemented as a feature? \$\endgroup\$ Jun 4, 2018 at 23:02
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Jun 5, 2018 at 12:32
  • 1
    \$\begingroup\$ Please merge the "Update" part. \$\endgroup\$
    – DELETE_ME
    Jun 5, 2018 at 13:39

19 Answers 19

12
\$\begingroup\$

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.split`x`.join`*x`.split`^`.join`**`)

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ I think you can save a couple bytes by using replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**')) \$\endgroup\$ Jun 4, 2018 at 19:50
  • \$\begingroup\$ @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. \$\endgroup\$
    – Arnauld
    Jun 4, 2018 at 20:00
  • 2
    \$\begingroup\$ @RickHitchcock If we can take X in uppercase, then we can do a<{}?'*X':'**', saving a byte. Hence my question to the OP. \$\endgroup\$
    – Arnauld
    Jun 4, 2018 at 20:03
  • 1
    \$\begingroup\$ cant handle x alone \$\endgroup\$
    – l4m2
    Jun 7, 2018 at 9:01
  • 1
    \$\begingroup\$ @l4m2 The challenge rules were updated. :/ It used to be 1x for x. \$\endgroup\$
    – Arnauld
    Jun 7, 2018 at 9:08
8
\$\begingroup\$

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!

\$\endgroup\$
0
8
\$\begingroup\$

Python 3, 53 50 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.

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

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!

\$\endgroup\$
0
4
\$\begingroup\$

Japt 2.0, 13 bytes

OvUd^'*²'x"*V

Try it.

Explanation:

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

Ov            Eval:
  Ud            In U, replace:
    ^             "^" with:
     '*²            "**"
        'x        "x" with:
          "*V       "*V"
\$\endgroup\$
4
\$\begingroup\$

Wolfram Language (Mathematica), 22 bytes

ToExpression@#/.x->#2&

Try it online!

\$\endgroup\$
4
\$\begingroup\$

JavaScript (Node.js), 113 108 bytes

_=>x=>_.match(/-?(?:[x\d]+|\^?)+/g).reduce((a,b)=>b.split`x`[0]*(~b.indexOf`x`?x**(b.split`^`[1]||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` 
                        [0]     // and select the first instance 
                * (b.indexOf`x` // 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]||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

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

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.
\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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')[0])*(b.indexOf('x')>0?Math.pow(x,(l=(b.split('^')[1]))?l:1):1)+a,0)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Jun 5, 2018 at 4:58
2
\$\begingroup\$

Physica, 35 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Jelly, 21 bytes

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

Try it online!

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

Java 8, 150 149 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..

\$\endgroup\$
8
  • \$\begingroup\$ JavaScript does support ** (ES7+), why does this not support that ? \$\endgroup\$ Jun 4, 2018 at 14:16
  • \$\begingroup\$ Also is there no eval in java. That can't be right ? \$\endgroup\$ Jun 4, 2018 at 14:17
  • \$\begingroup\$ @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+.. \$\endgroup\$ Jun 4, 2018 at 14:20
  • \$\begingroup\$ Man, java sucks, no eval why ? Okay why hasn't it been updated ? \$\endgroup\$ Jun 4, 2018 at 14:21
  • 1
    \$\begingroup\$ Yes, there's an eval in java, since Java 9. \$\endgroup\$ Jun 4, 2018 at 22:54
2
\$\begingroup\$

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
\$\endgroup\$
1
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

Octave, 47 38 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.

\$\endgroup\$
1
\$\begingroup\$

Ruby, 43 bytes

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

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice approach with hash replacement, but straight two gsubs are even shorter \$\endgroup\$
    – Kirill L.
    Jun 4, 2018 at 13:34
1
\$\begingroup\$

Perl 5 -pl, 35 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 19 bytes

(x=#;ToExpression)&

Try it online!

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.