Evaluar cadena de expresión polinómica

18

Cree una función que tome una ecuación polinómica, un valor para xy devuelva el resultado de la operación.

Ejemplo: dado 4x^2+2x-5y x=3salida 37. Este es el resultado de4(3)^2+2(3)-5

  • Suponga que todos los polinomios son válidos
  • El formato polinómico siempre será coefficient(variable)^exponent => 4x^2excepto:
    • Cuando el exponente es 1serácoefficient(variable) => 4x
    • Cuando el coeficiente es 1será(variable)^exponent => x^2
  • Los polinomios son solo una variable
  • El uso de bibliotecas externas está prohibido.
  • El coeficiente y la entrada variable pueden ser números positivos y negativos.

Casos de prueba

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

Actualizar

  • El formato polinómico siempre será coefficient(variable)^exponent => 4x^2excepto:
    • Cuando el exponente es 1serácoefficient(variable) => 4x
    • Cuando el coeficiente es 1será(variable)^exponent => x^2
  • Se eliminó la regla del exponente negativo. Mi error. Un polinomio válido no contiene exponente negativo
  • Un exponente de 0sería solocoefficient
  • Se agregó un caso de prueba para input 0

Este es el , por lo que gana la respuesta más corta en bytes.

Luis felipe De jesus Munoz
fuente
3
¿Qué tan flexible es el formato de entrada? En lugar de 3x^3-5x^2+2x-10podemos ingresar 3*x^3-5*x^2+2*x-10? O [3 -5 2 -10]. [3 2 1 0]?
Luis Mendo
1
@Arnauld Sí ...
Luis felipe De jesus Munoz
44
¿Qué es una "biblioteca externa" y cómo es justa, en comparación con los idiomas que ya tienen "eval" implementada como característica?
Olivier Grégoire
1
Mis disculpas, no he usado mi PC desde ayer. He actualizado el desafío con las sugerencias que me diste. Míralo y vuelve a abrirlo si todo está bien.
Luis felipe De jesus Munoz

Respuestas:

12

JavaScript (ES7), 48 bytes

Basado en una sugerencia de @RickHitchcock

Espera Xen mayúsculas. Toma entrada en la sintaxis de curry (p)(X).

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

Pruébalo en línea!


JavaScript (ES7), 49 bytes

El mismo enfoque que @DeadPossum . Toma entrada en la sintaxis de curry (p)(x).

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

Pruébalo en línea!

Arnauld
fuente
1
Creo que puede guardar un par de bytes usando replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Rick Hitchcock
@RickHitchcock No puedo usar una referencia a fmenos que esté incluida en el recuento de bytes, a costa de los 2 bytes que se supone que se guardarán. Sin embargo, me gusta este método. Puede haber una manera de guardar un byte o dos actualizándolo de alguna manera.
Arnauld
2
@RickHitchcock Si podemos usar Xmayúsculas, entonces podemos hacerlo a<{}?'*X':'**', guardando un byte. De ahí mi pregunta al OP.
Arnauld
1
no puedo manejar xsolo
l4m2
1
@ l4m2 Se actualizaron las reglas de desafío. : / Solía ​​ser 1xpara x.
Arnauld
8

Python 2 , 54 bytes

-2 bytes gracias a Jo King

-5 bytes gracias a Arnauld

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

Pruébalo en línea!

Zarigüeya muerta
fuente
8

Python 3 , 53 50 48 bytes

editar : -5 bytes gracias a Dennis!

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

Pruébalo en línea!

Se usa translatepara evitar encadenar replacellamadas; La versión de Python 3 translatees menos incómoda que la de su predecesora.

etene
fuente
"*(%d)"%xpuede llegar a ser "*(x)".
Dennis
¡Gracias, no me había dado cuenta de que el evento xestaba dentro de mi evalalcance! Voy a actualizar
etene
1
En realidad, dado xque ya no es una representación de cadena, también "*x"funciona.
Dennis
Aun mejor ! Gracias de nuevo.
etene
5

R , 44 bytes

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

Pruébalo en línea!

Bastante sencillo con R. Reemplazar nxcon n*xy luego evalla parsecadena d. xse usa ya que así es como nombramos el segundo argumento.

La función eval podría incluso ser utilizado de manera más directa con un primer argumento con el formato correcto, y otros argumentos formales ( y, z, etc.) podría ser fácilmente añadidos:

R , 20 bytes (no competitivos)

function(f,x)eval(f)

Pruébalo en línea!

JayCe
fuente
4

Japt 2.0, 13 bytes

OvUd^'*²'x"*V

Probarlo .

Explicación:

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

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

JavaScript (Node.js) , 113108 bytes

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

Pruébalo en línea!

Gracias a @Arnauld


Dado que la mejor solución JS hasta el momento por @Arnauld (49 bytes) ya ha sido publicada y se usa eval, decidí usar Regex y reducir en lugar de eso.

Aunque bastante largo en comparación con el suyo.

Explicacion:

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
fuente
Esto falla actualmente en el último caso de prueba (debe ser 0.25). Puede guardar algunos bytes utilizando en -lugar de [-], en ~b.indexOf`x` lugar de b.indexOf`x`>0y eliminando el l=que no se utiliza. (Pero esto no soluciona el error).
Arnauld
@Arnauld: Gracias. No tengo idea de por qué hace eso, veré cuál es el problema
Muhammad Salman
Bueno, el problema es que tu expresión regular se divide 1x^-2en el -.
Arnauld
3

05AB1E , 16 19 bytes

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

+3 bytes como corrección de errores para entrada negativa x.

.E ( Ejecutar como código de lote ) se ha reemplazado con Ejecutar como Pythoneval en esta última confirmación de @Adnan , pero esta versión aún no está en TIO. @ Mr.Xcoder lo probó en su local (última versión) 05AB1E para verificar que funciona.
Vea esta versión sin .Ever cómo convirtió la cadena de expresión.

Explicación:

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

Programa alternativo de 25 28 bytes que funciona en la versión actual de TIO:

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

Pruébalo en línea.

Explicación:

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

“…¢(“es la cadena print(porque:

  • y comienza y termina la cadena comprimida
  • …¢es igual a 0426porque mira los índices en el archivo info.txt , donde tiene el índice 4 y ¢tiene el índice 26.
  • Este índice 0426se usa luego en el archivo del diccionario , donde la línea 427 (índice 426) es la palabra que busca, que es printen este caso.
  • El (no tiene un índice en el archivo info.txt, por lo que se interpreta como es.
Kevin Cruijssen
fuente
2

JavaScript (Node.js) , 143 bytes

Sé que hay mejores respuestas, pero quería hacerlo sin usar 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)

Pruébalo en línea!

Luis felipe De jesus Munoz
fuente
Tu expresión regular no necesita, [a-z0-9.]¿verdad? La única letra que puede aparecer es x. ¿Por qué .? No necesita manejar coeficientes o exponentes no enteros.
Peter Cordes
2

Jalea , 21 bytes

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

Pruébalo en línea!

Erik el Outgolfer
fuente
Debido a la precedencia del operador, esto no funciona ("-20x^2+20x-50", -8).
Dennis
@Dennis Ajustado en consecuencia.
Erik the 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)"))

No estoy seguro de si es posible tener una función lambda curry que arroje una excepción. Si es así, se puede guardar 1 byte cambiando (s,n)->a n->s->. -1 byte gracias a @ OlivierGrégoire por mostrarme cómo hacer esto.

Pruébalo en línea.

Explicación:

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)

Desafortunadamente, la evaluación de JavaScript no es compatible **, por lo que tengo que usar un reemplazo más largo para convertirla en su Math.powlugar ...

Kevin Cruijssen
fuente
JavaScript admite **(ES7 +), ¿por qué esto no admite eso?
Muhammad Salman
Además, ¿no hay evaluación en Java? Eso no puede estar bien?
Muhammad Salman
@MuhammadSalman No, Java no tiene eval. Y creo que esta evaluación de JavaScript incorporada que puedo usar ScriptEngineManagerno se ha actualizado en Java JDK durante años, por lo que no es compatible ES7+...
Kevin Cruijssen
Hombre, Java apesta, no eval, ¿por qué? ¿Por qué no se ha actualizado?
Muhammad Salman
@MuhammadSalman No sé ... Tendrás que hacer esa pregunta a los creadores de Java. ;)
Kevin Cruijssen
2

TI-Basic, 6 bytes

Prompt X:expr(Ans

La expresión se toma como argumento y se ingresa X durante el tiempo de ejecución. Alternativamente 8 bytes sin expr:

Prompt X,u:u

Aquí se ingresan ambos argumentos en tiempo de ejecución.

Timtech
fuente
2

Octava , 47 38 37 bytes

Ahorró muchos bytes al tomar la segunda entrada como una cadena en lugar de un número.

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

Pruébalo en línea!

Explicación:

Bastante sencillo: reemplazar xpor (c), donde ces la segunda entrada, y evaluar. Los paréntesis son necesarios porque en Octave -8^2 == -64.

Stewie Griffin
fuente
1

Ruby , 43 41 bytes

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

Pruébalo en línea!

Guardado dos bytes gracias a @ Mr.Xcoder


Como todavía no hay una respuesta de Ruby, agregué una. Nvm hubo uno que usó un enfoque diferente

Explicacion:

->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
fuente
1

Excel, 36 + 2 bytes, no competidor

Evaluar un campo de texto como una fórmula no es sencillo en Excel. Hay un escondido=EVALUATE() función , a la que se puede llamar definiendo un Nombre.

En Excel 2007, Fórmulas> Definir nombre. Definir un nombre llamado E, con referencias a:

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

Luego, con la entrada de Fórmula adentro A1, el xvalor adentro B1, ingresando =Een el C1resultado esperado.

Wernisch
fuente