Valuta la stringa di espressione polinomiale


18

Creare una funzione che accetta un'equazione polinomiale, un valore per xe restituisce il risultato dell'operazione.

Esempio: dato 4x^2+2x-5e x=3prodotto 37. Questo è il risultato di4(3)^2+2(3)-5

  • Supponiamo che tutti i polinomi siano validi
  • Il formato polinomiale sarà sempre coefficient(variable)^exponent => 4x^2tranne:
    • Quando esponente 1saràcoefficient(variable) => 4x
    • Quando sarà il coefficiente 1sarà(variable)^exponent => x^2
  • I polinomi sono solo una variabile
  • È vietato l'uso di biblioteche esterne
  • Il coefficiente e l'input variabile possono essere numeri positivi e negativi.

Casi test

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

Aggiornare

  • Il formato polinomiale sarà sempre coefficient(variable)^exponent => 4x^2tranne:
    • Quando esponente 1saràcoefficient(variable) => 4x
    • Quando sarà il coefficiente 1sarà(variable)^exponent => x^2
  • Rimossa la regola dell'esponente negativo. Errore mio. Un polinomio valido non contiene esponente negativo
  • Un esponente di 0sarebbe giustocoefficient
  • Aggiunto test case per input 0

Questo è , quindi vince la risposta più breve in byte.


3
Quanto è flessibile il formato di input? Invece di 3x^3-5x^2+2x-10possiamo inserire 3*x^3-5*x^2+2*x-10? Oppure [3 -5 2 -10]. [3 2 1 0]?
Luis Mendo,

1
@Arnauld Sì ...
Luis felipe De jesus Munoz,

4
Che cos'è una "biblioteca esterna" e come è corretta, rispetto alle lingue che hanno "eval" già implementato come funzionalità?
Olivier Grégoire,

1
Mi scuso, non uso il mio pc da ieri. Ho aggiornato la sfida con i suggerimenti che mi hai dato. Dai un'occhiata e riaprilo se tutto è a posto.
Luis felipe De jesus Munoz,

Risposte:


12

JavaScript (ES7), 48 byte

Sulla base di un suggerimento di @RickHitchcock

Si aspetta Xin maiuscolo. Accetta input nella sintassi del curry (p)(X).

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

Provalo online!


JavaScript (ES7), 49 byte

Stesso approccio di @DeadPossum . Accetta input nella sintassi del curry (p)(x).

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

Provalo online!


1
Penso che puoi salvare un paio di byte usando replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Rick Hitchcock il

@RickHitchcock Non posso usare un riferimento a fmeno che non sia incluso nel conteggio dei byte, al costo dei 2 byte che dovrebbero essere salvati. Mi piace questo metodo, comunque. Potrebbe esserci un modo per salvare un byte o due rinnovandolo in qualche modo.
Arnauld,

2
@RickHitchcock Se possiamo prendere Xin maiuscolo, allora possiamo farlo a<{}?'*X':'**', salvando un byte. Da qui la mia domanda all'OP.
Arnauld,

1
non posso gestire xda solo
l4m2

1
@ l4m2 Le regole della sfida sono state aggiornate. : / Era 1xper x.
Arnauld,


8

Python 3 , 53 50 48 byte

modifica : -5 byte grazie a Dennis!

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

Provalo online!

Utilizzato translateper evitare replacechiamate concatenate ; La versione di Python 3 translateè meno imbarazzante di quella del suo predecessore.


"*(%d)"%xpuò diventare "*(x)".
Dennis,

Grazie, non avevo capito che xera nel mio evalcampo di applicazione! Aggiornerò.
etene,

1
In realtà, poiché xnon è più una rappresentazione in forma di stringa, "*x"funziona anche.
Dennis,

Anche meglio ! Grazie ancora.
etene,

5

R , 44 byte

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

Provalo online!

Abbastanza semplice con R. Sostituisci nxcon n*xe poi evalla parsestringa d. xviene utilizzato in questo modo viene chiamato il secondo argomento.

La funzione eval potrebbe anche essere utilizzato in modo più diretto con un primo argomento formattato correttamente, e altri argomenti formali ( y, z, ecc) potrebbe essere facilmente aggiunto:

R , 20 byte (non concorrenti)

function(f,x)eval(f)

Provalo online!


4

Japt 2.0, 13 byte

OvUd^'*²'x"*V

Provatelo .

Spiegazione:

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

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


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)

Provalo online!

Grazie a @Arnauld


Poiché la migliore soluzione JS finora di @Arnauld (49 byte) è già stata pubblicata e utilizza eval, ho deciso di utilizzare Regex e ridurlo invece di quello.

Abbastanza lungo rispetto al suo però.

Spiegazione :

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


Questo al momento fallisce nell'ultimo caso di test (dovrebbe essere 0,25). È possibile salvare alcuni byte utilizzando -invece di [-], ~b.indexOf`x` anziché b.indexOf`x`>0e rimuovendo ciò l=che non viene utilizzato. (Ma questo non risolve il problema.)
Arnauld

@Arnauld: grazie. Non ho idea del perché lo farà, vedrà qual è il problema
Muhammad Salman,

Bene, il problema è che il tuo regex si divide 1x^-2su -.
Arnauld,

3

05AB1E , 16 19 byte

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

+3 byte come correzione di bug per input negativo x.

.E( Esegui come Codice del lotto ) è stato sostituito con Esegui come Pythoneval in questo ultimo commit di @Adnan , ma questa versione non è su TIO ancora. @ Mr.Xcoder lo ha testato sul suo 05AB1E locale (ultima versione) per verificarne il funzionamento.
Vedi questa versione senza .Evedere come ha convertito la stringa di espressione.

Spiegazione:

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

Programma alternativo da 25 28 byte che funziona con la versione corrente di TIO:

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

Provalo online.

Spiegazione:

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

“…¢(“è la stringa print(, perché:

  • e inizia e termina la stringa compressa
  • …¢è uguale a 0426perché esamina gli indici nel file info.txt , dove ha l'indice 4 e l' ¢indice 26.
  • Questo indice 0426viene quindi utilizzato nel file di dizionario , dove la riga 427 (indice 426) è la parola che recupera, che è printin questo caso.
  • Il (non avere un indice nel file info.txt, quindi è interpretare come è.

2

JavaScript (Node.js) , 143 byte

So che ci sono risposte migliori ma volevo farlo senza usare 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)

Provalo online!


Il tuo regex non ne ha bisogno [a-z0-9.]? L'unica lettera che può apparire è x. Qualche perchè .? Non è necessario gestire coefficienti o esponenti non interi.
Peter Cordes,



2

Java 8, 150 149 148 byte

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

Non sono sicuro se è possibile avere una funzione lambda al curry che genera un'eccezione. In tal caso, è possibile salvare 1 byte cambiando(s,n)-> in n->s->. -1 byte grazie a @ OlivierGrégoire per avermi mostrato come fare.

Provalo online.

Spiegazione:

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)

Purtroppo JavaScript eval non supporta **, quindi devo usare un sostituto più lungo per convertirlo in Math.powinvece ..


JavaScript supporta **(ES7 +), perché questo non lo supporta?
Muhammad Salman,

Inoltre non c'è valutazione a java. Non può essere vero?
Muhammad Salman,

@MuhammadSalman No, Java non ha eval. E penso che questo JavaScript-eval incorporato che posso usare ScriptEngineManagernon sia stato aggiornato nel Java JDK per anni, quindi non supporta ES7+..
Kevin Cruijssen,

Amico, Java fa schifo, niente male perché? Va bene perché non è stato aggiornato?
Muhammad Salman,

@MuhammadSalman Non lo so .. Dovrai porre questa domanda ai creatori di Java. ;)
Kevin Cruijssen il

2

TI-Basic, 6 byte

Prompt X:expr(Ans

L'espressione viene considerata come argomento e X viene inserito durante il runtime. In alternativa 8 byte senzaexpr :

Prompt X,u:u

Qui entrambi gli argomenti vengono inseriti in fase di esecuzione.


2

Ottava , 47 38 37 byte

Ho salvato molti byte prendendo il secondo input come stringa anziché come numero.

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

Provalo online!

Spiegazione:

Abbastanza semplice: sostituisci xcon (c), dove si ctrova il secondo input e valuta. Le paretesi sono necessarie perché in Ottava -8^2 == -64.




1

Rubino , 43 41 byte

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

Provalo online!

Due byte salvati grazie a @ Mr.Xcoder


Poiché non esiste ancora una risposta di Ruby, ne ho aggiunta una. Nvm ce n'era uno che utilizzava un approccio diverso

Spiegazione :

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


1

Excel, 36 + 2 byte, senza concorrenza

La valutazione di un campo di testo come formula non è semplice in Excel. C'è una =EVALUATE()funzione nascosta , che può essere chiamata definendo un Nome.

In Excel 2007, Formule> Definisci nome. Definisci un nome chiamato E, con riferimento a:

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

Quindi, con Formula input in A1, xvalue in B1, immettendo =Ein C1return il risultato atteso.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.