Polynomausdruckszeichenfolge auswerten

18

Erstellen Sie eine Funktion, die eine Polynomgleichung, einen Wert für xund das Ergebnis der Operation zurückgibt.

Beispiel: gegeben 4x^2+2x-5und x=3ausgegeben 37. Dies ist das Ergebnis von4(3)^2+2(3)-5

  • Angenommen, alle Polynome sind gültig
  • Das Polynomformat ist immer coefficient(variable)^exponent => 4x^2außer:
    • Wenn Exponent ist 1, wird es seincoefficient(variable) => 4x
    • Wenn Koeffizient ist 1, wird es sein(variable)^exponent => x^2
  • Polynome sind nur eine Variable
  • Die Verwendung externer Bibliotheken ist untersagt
  • Der Koeffizient und die variable Eingabe können positive und negative Zahlen sein.

Testfälle

  • ("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

Aktualisieren

  • Das Polynomformat ist immer coefficient(variable)^exponent => 4x^2außer:
    • Wenn Exponent ist 1, wird es seincoefficient(variable) => 4x
    • Wenn Koeffizient ist 1, wird es sein(variable)^exponent => x^2
  • Die Regel des negativen Exponenten wurde entfernt. Mein Fehler. Ein gültiges Polynom enthält keinen negativen Exponenten
  • Ein Exponent von 0wäre gerechtcoefficient
  • Testfall für hinzugefügt input 0

Das ist , also gewinnt die kürzeste Antwort in Bytes.

Luis Felipe De Jesus Munoz
quelle
3
Wie flexibel ist das Eingabeformat? Anstelle von 3x^3-5x^2+2x-10können wir eingeben 3*x^3-5*x^2+2*x-10? Oder [3 -5 2 -10]. [3 2 1 0]?
Luis Mendo
1
@ Arnauld Ja ...
Luis Felipe De Jesus Munoz
4
Was ist eine "externe Bibliothek" und wie ist sie fair im Vergleich zu Sprachen, die "eval" bereits als Feature implementiert haben?
Olivier Grégoire
1
Entschuldigung, ich habe meinen PC seit gestern nicht mehr benutzt. Ich habe die Herausforderung mit den Vorschlägen aktualisiert, die Sie mir gegeben haben. Bitte schauen Sie es sich an und öffnen Sie es erneut, wenn alles in Ordnung ist.
Luis Felipe De Jesus Munoz

Antworten:

12

JavaScript (ES7), 48 Byte

Basiert auf einem Vorschlag von @RickHitchcock

Erwartet Xin Großbuchstaben. Übernimmt Eingaben in der Currying-Syntax (p)(X).

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

Probieren Sie es online!


JavaScript (ES7), 49 Byte

Gleicher Ansatz wie @DeadPossum . Übernimmt Eingaben in der Currying-Syntax (p)(x).

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

Probieren Sie es online!

Arnauld
quelle
1
Ich denke, Sie können ein paar Bytes sparen, indem Sie replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Rick Hitchcock
@ RickHitchcock Ich kann keinen Verweis auf verwenden, es fsei denn, er ist in der Byteanzahl enthalten, auf Kosten der 2 Bytes, die gespeichert werden sollen. Ich mag diese Methode allerdings. Es könnte eine Möglichkeit geben, ein oder zwei Bytes zu speichern, indem Sie es irgendwie überarbeiten.
Arnauld
2
@RickHitchcock Wenn wir XGroßbuchstaben erfassen können, können wir a<{}?'*X':'**'ein Byte speichern. Daher meine Frage an das OP.
Arnauld
1
kippe Griff xallein
l4m2
1
@ l4m2 Die Herausforderungsregeln wurden aktualisiert. : / Früher war es 1xfür x.
Arnauld
8

Python 2 , 54 Bytes

-2 Bytes dank Jo King

-5 Bytes danke an Arnauld

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

Probieren Sie es online!

Totes Opossum
quelle
8

Python 3 , 53 50 48 Bytes

edit : -5 bytes danke an Dennis!

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

Probieren Sie es online!

Wird verwendet translate, um das Verketten von replaceAnrufen zu vermeiden . Die Version von Python 3 translateist weniger umständlich als die des Vorgängers.

Eten
quelle
"*(%d)"%xwerden kann "*(x)".
Dennis
Vielen Dank, ich hatte nicht herausgefunden, dass xes in meinem evalAnwendungsbereich liegt! Ich werde aktualisieren.
Etene
1
Eigentlich funktioniert das auch , da xes keine String-Darstellung mehr gibt "*x".
Dennis
Noch besser ! Danke noch einmal.
Etene
5

R , 44 Bytes

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

Probieren Sie es online!

Ziemlich einfach mit R. Ersetzen Sie nxmit n*xund dann evaldie parsed-Zeichenfolge. xwird verwendet, da wir so das zweite Argument nennen.

Die Funktion eval könnte noch direkt mit einem richtig formatierte erstes Argumente und andere formale Argumente (verwendet werden y, zusw.) leicht hinzugefügt werden könnten:

R , 20 Bytes (nicht konkurrierend)

function(f,x)eval(f)

Probieren Sie es online!

JayCe
quelle
4

Japt 2.0, 13 Bytes

OvUd^'*²'x"*V

Probieren Sie es aus .

Erläuterung:

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

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

JavaScript (Node.js) , 113 108 Byte

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

Probieren Sie es online!

Vielen Dank an @Arnauld


Da die bisher beste JS-Lösung von @Arnauld (49 Bytes) bereits gepostet wurde und sie verwendet eval, habe ich mich für Regex entschieden und stattdessen reduziert.

Ziemlich lang im Vergleich zu seinem.

Erklärung:

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

Muhammad Salman
quelle
Dies schlägt derzeit im letzten Testfall fehl (sollte 0,25 sein). Sie können mit ein paar Bytes speichern -statt [-], ~b.indexOf`x` statt b.indexOf`x`>0und Entfernen l=der nicht verwendet wird. (Aber das behebt den Fehler nicht.)
Arnauld
@ Arnauld: Danke. Keine Ahnung, warum es das tut, wird sehen, was das Problem ist
Muhammad Salman
Nun, das Problem ist, dass sich Ihr Regex 1x^-2auf dem aufspaltet -.
Arnauld
3

05AB1E , 16 bis 19 Bytes

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

+3 Bytes als Bugfix für negative Eingaben x.

.E( Als Batch-Code ausführen ) wurde in diesem letzten Commit von @Adnan durch Als Python evalausführen ersetzt , aber diese Version ist noch nicht in TIO. @ Mr.Xcoder hat es auf seiner lokalen (neuesten Version) 05AB1E getestet, um zu überprüfen, ob es funktioniert. Sehen Sie sich diese Version an, ohne zu sehen, wie die Ausdruckszeichenfolge konvertiert wurde.
.E

Erläuterung:

„*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-Byte- Programm, das auf der aktuellen Version von TIO funktioniert:

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

Probieren Sie es online aus.

Erläuterung:

„*(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

“…¢(“ist die Zeichenfolge print(, weil:

  • und startet und beendet die komprimierte Zeichenfolge
  • …¢ist gleich, 0426weil es die Indizes in der Datei info.txt betrachtet , wobei Index 4 und ¢Index 26 vorhanden sind.
  • Dieser Index 0426wird dann in der Wörterbuchdatei verwendet , wobei Zeile 427 (Index 426) das Wort ist, das abgerufen wird, was printin diesem Fall der Fall ist.
  • Das (hat keinen Index in der info.txt-Datei, also interpretiert es so wie es ist.
Kevin Cruijssen
quelle
2

JavaScript (Node.js) , 143 Byte

Ich weiß, dass es bessere Antworten gibt, aber ich wollte es tun, ohne eval zu verwenden

(_,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)

Probieren Sie es online!

Luis Felipe De Jesus Munoz
quelle
Dein Regex braucht das nicht [a-z0-9.]? Der einzige Buchstabe, der angezeigt werden kann, ist x. Warum auch immer .? Sie müssen keine nicht ganzzahligen Koeffizienten oder Exponenten verarbeiten.
Peter Cordes
2

Jelly , 21 Bytes

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

Probieren Sie es online!

Erik der Outgolfer
quelle
Aufgrund der Priorität des Operators funktioniert dies nicht für ("-20x^2+20x-50", -8).
Dennis
@ Tennis entsprechend angepasst.
Erik der Outgolfer
2

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)"))

Ich bin nicht sicher, ob es möglich ist, eine Lambda-Curry-Funktion zu verwenden, die eine Ausnahme auslöst. Wenn ja, 1 Byte kann zu ändern werden gespeichert (s,n)->zu n->s->.-1 Byte Danke an @ OlivierGrégoire für die Anleitung .

Probieren Sie es online aus.

Erläuterung:

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)

Leider wird die JavaScript-Evaluierung nicht unterstützt **, sodass ich Math.powstattdessen einen längeren Ersatz verwenden muss, um sie zu konvertieren .

Kevin Cruijssen
quelle
JavaScript unterstützt **(ES7 +), warum unterstützt dies das nicht?
Muhammad Salman
Auch gibt es keine eval in Java. Das kann doch nicht richtig sein?
Muhammad Salman
@ MuhammadSalman Nein, Java hat keine eval. Und ich denke, dass diese integrierte JavaScript-Evaluierung, mit der ich arbeiten kann, ScriptEngineManagerseit Jahren nicht mehr im Java JDK aktualisiert wurde, sodass sie nicht mehr unterstützt wird ES7+.
Kevin Cruijssen,
Mann, Java ist zum Kotzen, nein, warum? Okay, warum wurde es nicht aktualisiert?
Muhammad Salman
@ MuhammadSalman Ich weiß nicht .. Sie müssen die Schöpfer von Java diese Frage stellen. ;)
Kevin Cruijssen
2

TI-Basic, 6 Bytes

Prompt X:expr(Ans

Ausdruck wird als Argument genommen und X wird zur Laufzeit eingegeben. Alternativ 8 Bytes ohne expr:

Prompt X,u:u

Hier werden beide Argumente zur Laufzeit eingegeben.

Timtech
quelle
2

Oktave , 47 38 37 Bytes

Es wurden viele Bytes gespart, indem die zweite Eingabe als Zeichenfolge anstelle einer Zahl verwendet wurde.

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

Probieren Sie es online!

Erläuterung:

Ziemlich einfach: Ersetze xdurch (c), wo cist die zweite Eingabe, und bewerte. Die Parethesen sind da in Oktave notwendig -8^2 == -64.

Stewie Griffin
quelle
1

Ruby , 43 41 Bytes

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

Probieren Sie es online!

Zwei Bytes gespart dank @ Mr.Xcoder


Da es noch keine Ruby-Antwort gibt, habe ich eine hinzugefügt. Nvm gab es eine, die einen anderen Ansatz verwendet

Erklärung:

->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
Muhammad Salman
quelle
1

Excel, 36 + 2 Bytes, nicht konkurrierend

Das Auswerten eines Textfelds als Formel ist in Excel nicht einfach. Es gibt eine versteckte =EVALUATE()Funktion, die durch die Definition eines Namens aufgerufen werden kann.

In Excel 2007 Formeln> Name definieren. Definieren Sie einen Namen mit den folgenden Bezeichnungen E:

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

Dann wird mit Hilfe der Formel in Eingang A1, xWert B1, die Eingabe =Ein C1kehren erwartetes Ergebnis.

Wernisch
quelle