Avaliar sequência de expressão polinomial

18

Crie uma função que use uma equação polinomial, um valor para xe retorne o resultado da operação.

Exemplo: dado 4x^2+2x-5e x=3saída 37. Este é o resultado de4(3)^2+2(3)-5

  • Suponha que todos os polinômios são válidos
  • O formato polinomial será sempre, coefficient(variable)^exponent => 4x^2exceto:
    • Quando expoente é 1que serácoefficient(variable) => 4x
    • Quando o coeficiente for 1, será(variable)^exponent => x^2
  • Polinômios são apenas uma variável
  • É proibido o uso de bibliotecas externas
  • O coeficiente e a entrada variável podem ser números positivos e negativos.

Casos de teste

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

Atualizar

  • O formato polinomial será sempre, coefficient(variable)^exponent => 4x^2exceto:
    • Quando expoente é 1que serácoefficient(variable) => 4x
    • Quando o coeficiente for 1, será(variable)^exponent => x^2
  • Removida a regra do expoente negativo. Meu erro. Um polinômio válido não contém expoente negativo
  • Um expoente de 0seria apenascoefficient
  • Caso de teste adicionado para input 0

Isso é , então a resposta mais curta em bytes vence.

Luis felipe De jesus Munoz
fonte
3
Quão flexível é o formato de entrada? Em vez de 3x^3-5x^2+2x-10podemos inserir 3*x^3-5*x^2+2*x-10? Ou [3 -5 2 -10]. [3 2 1 0]?
Luis Mendo
1
@Arnauld Sim ...
Luis Felipe de Jesus Munoz
4
O que é uma "biblioteca externa" e como é justo, em comparação com os idiomas que "eval" já foram implementados como um recurso?
Olivier Grégoire
1
Minhas desculpas, eu não uso o meu pc desde ontem. Atualizei o desafio com as sugestões que você me deu. Por favor, dê uma olhada e reabra se tudo estiver ok.
Luis felipe De jesus Munoz
1
Por favor, mescle a parte "Atualizar".
usar o seguinte comando

Respostas:

12

JavaScript (ES7), 48 bytes

Com base em uma sugestão de @RickHitchcock

Espera Xem maiúsculas. Recebe entrada na sintaxe de currying (p)(X).

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

Experimente online!


JavaScript (ES7), 49 bytes

A mesma abordagem do @DeadPossum . Recebe entrada na sintaxe de currying (p)(x).

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

Experimente online!

Arnauld
fonte
1
Eu acho que você pode salvar alguns bytes usando replace: p=>x=>eval(p.replace(/[x^]/g,a=>a>f?'*x':'**'))
Rick Hitchcock
@ RickHitchcock Não posso usar uma referência a fmenos que esteja incluída na contagem de bytes, ao custo dos 2 bytes que devem ser salvos. Eu gosto desse método, no entanto. Pode haver uma maneira de salvar um byte ou dois, renovando-o de alguma forma.
Arnauld
2
@ RickHitchcock Se pudermos usar Xmaiúsculas, podemos fazê-lo a<{}?'*X':'**', salvando um byte. Daí a minha pergunta para o OP.
Arnauld
1
não podem lidar xsozinhos
l4m2
1
@ l4m2 As regras do desafio foram atualizadas. : / Costumava ser 1xpara x.
Arnauld
8

Python 2 , 54 bytes

-2 bytes graças a Jo King

-5 bytes graças a Arnauld

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

Experimente online!

Gambá morto
fonte
8

Python 3 , 53 50 48 bytes

editar : -5 bytes graças a Dennis!

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

Experimente online!

Usado translatepara evitar encadear replacechamadas; A versão do Python 3 translateé menos estranha do que a do seu antecessor.

eteno
fonte
"*(%d)"%xpode se tornar "*(x)".
Dennis
Obrigado, eu não tinha percebido que o evento xestava no meu evalescopo! Eu vou atualizar.
etene
1
Na verdade, como xnão é mais uma representação de strings, também "*x"funciona.
Dennis
Melhor ainda ! Obrigado novamente.
etene 4/18
5

R , 44 bytes

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

Experimente online!

Bastante simples com R. Substitua nxpor n*xe depois evalpela parsestring d. xé usado, pois é assim que chamamos o segundo argumento.

A função eval poderia até ser usado mais diretamente com um primeiro argumento formatado corretamente, e outros argumentos formais ( y, z, etc.) podem ser facilmente adicionados:

R , 20 bytes (não concorrente)

function(f,x)eval(f)

Experimente online!

JayCe
fonte
4

Japonês 2.0, 13 bytes

OvUd^'*²'x"*V

Experimente .

Explicação:

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

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

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)

Experimente online!

Obrigado a @Arnauld


Como a melhor solução JS até agora do @Arnauld (49 bytes) já foi publicada e utiliza eval , eu decidi usar o Regex e reduzir em vez disso.

Bastante demorado comparado com o dele.

Explicação:

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
fonte
Atualmente, isso falha no último caso de teste (deve ser 0,25). Você pode salvar alguns bytes usando em -vez de [-], em ~b.indexOf`x` vez de b.indexOf`x`>0e removendo o l=que não é usado. (Mas isso não corrigir o erro.)
Arnauld
@ Arnauld: Obrigado. Não faço ideia por que isso acontece, vai ver qual é o problema #
Muhammad Salman
Bem, o problema é que o seu regex se divide 1x^-2no -.
Arnauld
3

05AB1E , 16 19 bytes

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

+3 bytes como correção de erro para entrada negativa x.

.E( Executar como código de lote ) foi substituído por Executar como Pythoneval neste último commit do @Adnan , mas esta versão ainda não está no TIO. @ Mr.Xcoder testou em seu local (versão mais recente) 05AB1E para verificar se está funcionando.
Veja esta versão sem .Epara ver como ela converteu a string de expressão.

Explicação:

„*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 na versão atual do TIO:

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

Experimente online.

Explicação:

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

“…¢(“é a cadeia print(, porque:

  • e inicia e termina a sequência compactada
  • …¢é igual a 0426porque olha para os índices no arquivo info.txt , onde tem o índice 4 e o ¢índice 26.
  • Esse índice 0426é então usado no arquivo de dicionário , em que a linha 427 (índice 426) é a palavra que busca, que éprint nesse caso.
  • O (arquivo não possui um índice no arquivo info.txt, portanto é interpretado como está.
Kevin Cruijssen
fonte
2

JavaScript (Node.js) , 143 bytes

Eu sei que existem respostas melhores, mas eu queria fazer isso sem usar o 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)

Experimente online!

Luis felipe De jesus Munoz
fonte
Seu regex não precisa, [a-z0-9.]não é? A única letra que pode aparecer é x. Algum porque .? Você não precisa manipular coeficientes não inteiros ou expoentes.
Peter Cordes
2

Geléia , 21 bytes

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

Experimente online!

Erik, o Outgolfer
fonte
Devido à precedência do operador, isso não funciona ("-20x^2+20x-50", -8).
Dennis
@Dennis Ajustado de acordo.
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)"))

Não tenho certeza se é possível ter uma função lambda de currying que lança uma exceção. Se for, pode salvar 1 byte alterando (s,n)->para n->s->. -1 byte graças a @ OlivierGrégoire por me mostrar como fazer isso.

Experimente online.

Explicação:

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)

Infelizmente, o eval de JavaScript não suporta **, então tenho que usar uma substituição mais longa para convertê-lo Math.powem ..

Kevin Cruijssen
fonte
O JavaScript suporta **(ES7 +), por que isso não é compatível?
Muhammad Salman
Também não há avaliação em java. Isso não pode estar certo?
Muhammad Salman
@MuhammadSalman Não, Java não tem eval. E eu acho que isso incorporado JavaScript-eval posso usar com ScriptEngineManagernão foi atualizado no Java JDK durante anos, por isso não suporta ES7+..
Kevin Cruijssen
Cara, java é uma merda, sem avaliação por que? Ok, por que não foi atualizado?
Muhammad Salman
@MuhammadSalman Não sei .. Você terá que fazer essa pergunta aos criadores de Java. ;)
Kevin Cruijssen
2

TI-Basic, 6 bytes

Prompt X:expr(Ans

Expressão é tomada como argumento e X é inserido durante o tempo de execução. Alternativamente, 8 bytes sem expr:

Prompt X,u:u

Aqui os dois argumentos são inseridos no tempo de execução.

Timtech
fonte
2

Octave , 47 38 37 bytes

Economizou muitos bytes usando a segunda entrada como uma sequência em vez de um número.

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

Experimente online!

Explicação:

Bastante direto: substitua xpor (c), onde cestá a segunda entrada, e avalie. As parênteses são necessárias porque na oitava -8^2 == -64.

Stewie Griffin
fonte
1

Ruby , 43 bytes

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

Experimente online!

GB
fonte
Agradável abordagem com a substituição de hash, mas retas dois gsubs são ainda mais curtos
Kirill L.
1

Ruby , 43 41 bytes

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

Experimente online!

Economizou dois bytes graças a @ Mr.Xcoder


Como ainda não há uma resposta para Ruby, adicionei uma. Nvm, houve um que usou uma abordagem diferente

Explicação:

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

Excel, 36 + 2 bytes, Não concorrente

A avaliação de um campo de texto como uma fórmula não é direta no Excel. Há uma =EVALUATE()função oculta , que pode ser chamada definindo um Nome.

No Excel 2007, Fórmulas> Definir nome. Defina um Nome chamado E, com Refere-se a:

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

Em seguida, com a entrada na Fórmula A1, xvalor em B1, entrando =Eem C1retornos resultado esperado.

Wernisch
fonte