Introdução
Escreva um programa para calcular a derivada parcial de um polinômio (possivelmente multivariado) com relação a uma variável.
Desafio
Derivadas são ferramentas matemáticas muito importantes que foram amplamente aplicadas em física, química, biologia, economia, psicologia e muito mais para lidar com todos os tipos de problemas. Expressões com múltiplas variáveis também são muito comuns.
No escopo deste desafio, uma sequência polinomial ("polystr") é definida pelo seguinte BNF (formato Backus – Naur):
<polystr> ::= <term> | <term><plusminus><polystr>
<plusminus> ::= "+" | "-"
<term> ::= <coeff> | <coeff><baseterm> | <baseterm>
<baseterm> ::= <variable> | <variable><exponent> | <baseterm><baseterm>
<coeff> ::= positive_integer
<exponent> ::= positive_integer
<variable> ::= lowercase_ASCII_letters
Onde positive_integer
e lowercase_ASCII_letters
são bastante auto-explicativos.
Por exemplo, A cadeia 3x2y-x3y-x2y+5
significa 3*(x^2)*y-(x^3)*y-(x^2)*y+5
. Os termos dados na entrada podem aparecer em qualquer ordem, e as variáveis em cada termo também podem aparecer em qualquer ordem. Por exemplo, 5-yx2-x3y+y3x2
também é uma entrada válida e é de fato o mesmo que o exemplo anterior.
A regra para obter derivada parcial é apenas fazê-lo termo a termo. Se a variável aparecer não aparecer no termo, a derivada será zero. Caso contrário, o coeficiente do termo é multiplicado pelo expoente dessa variável e, em seguida, o expoente da variável é diminuído de um. Os expoentes para outras variáveis não são alterados. Isso está apenas seguindo a definição em matemática. Além disso, se o expoente resultante for zero, remova a variável do termo.
Por exemplo, para tirar a derivada parcial de 5z-z2y2-5w3y
em relação a y
. O processo a seguir é realizado (de acordo com o BNF definido acima, o "coeficiente" é considerado um número positivo, ou seja, os sinais são considerados separadamente)
5z - z2y2 - 5w3y
Coeff 1->1*2=2 5->5*1=5
Expon 2->2-1=1 1->1-1=0
Term - 2yz2 - 5w3
(y is not here (expon 0->y removed)
so the term is 0)
O resultado é -2yz2-5w3y
.
Por outro lado, se a expressão acima é derivada parcial em relação a a
, o resultado é 0
porque não a
está em nenhum dos termos.
Sua tarefa é escrever uma função ou um programa completo para calcular essa derivada. Ele deve pegar uma sequência polinomial e um único caractere (a variável a qual derivar) e retornar a derivada da forma mais simples.
"Forma mais simples" significa três coisas.
O número
0
(não o dígito) não deve aparecer na saída, a menos que a saída seja justa0
. Portanto, nem0+10y
nem3-y0z
será uma saída válida e deve ser transformada em10y
e3-z
, respectivamente.O número
1
não deve aparecer como expoente ou coeficiente, mas pode aparecer como um termo independente.Os termos com exatamente o mesmo conjunto de variáveis e expoentes devem ser mesclados, o que significa que
3a2b5-4b5a2
não é uma saída válida e deve ser-a2b5
. Mais informações sobre entrada e saída podem ser encontradas na seção "Especificações".
Casos de teste
Input
Output
2xy+4ax-5+7mx4-4-7x4m, x
2y+4a
4upv+5u2v3w4-4w4u2v3+qr-v,v
4up+3u2v2w4-1
12ux-7x2m3+ab5,q
0
-a+10ca11y-1nv3rt3d-poly, a
-1+110ca10y
1y+1x3y, y
1+x3
Especificações
- A entrada pode ser obtida através de formulários padrão . Em outras palavras, você pode considerar a entrada como uma string, uma lista de caracteres, uma matriz aninhada de coeficientes, variáveis (possivelmente indicadas pelo valor ASCII menos 'a' ou algo parecido) e expoentes, etc. Você também pode mudar a string para
2*x^3y^2
ou semelhante em vez de2x3y2
.
No entanto, não use a entrada [2,0,0,0,1,0,0,3,0,0,...0]
(uma matriz de 27 elementos) para o termo 2dg
ou qualquer outro formato detalhado que enumere as 26 letras como esta. Seu formato de entrada também deve poder tratar ab
e ba
como entradas diferentes (portanto, o formato da matriz de 27 elementos é inválido devido a essa restrição também).
Cada variável (letra) aparecerá apenas uma vez em cada termo da entrada, o que significa
xx
que não aparecerá e sempre será apresentado comox2
, nem algo parecidoa3b4a2
.Para reiterar, os termos na entrada podem aparecer em qualquer ordem.
Você também pode escolher o formato de saída, desde que o formato detalhado mencionado acima seja evitado. No entanto, a saída deve sempre estar na forma mais simples, conforme definido acima. Assim como a entrada, os termos na saída podem aparecer em qualquer ordem, e as variáveis em cada termo também podem aparecer em qualquer ordem e não precisam ser consistentes entre os termos. Isso significa que
pu+2up2
é uma saída válida. O sinal para o termo líder pode ser positivo ou negativo e-y+3x
e3x-y
são ambos válidos, assim é+3x-y
.A entrada é sempre fornecida de forma que todos os coeficientes e expoentes na saída sejam menores que 2 32 -1, ou o maior número inteiro que seu idioma pode suportar, o que for menor. Afirmar que o maior número inteiro que seu idioma pode manipular é excessivamente pequeno e trivializar o desafio se enquadra na categoria de brechas padrão.
Isso é código-golfe , o menor número de bytes vence.
Como sempre, as brechas padrão se aplicam aqui.
Edit: Como a maioria das respostas até agora são internas que fazem todo o desafio, e, apesar de saber que existem componentes internos, não tenho a intenção de banir essas internas desde o início, nem o tenho agora. Farei com que os critérios de vencimento sejam baseados em cada idioma, ou seja, a submissão com o mínimo de bytes em cada idioma vence nesse idioma. Adicionarei um snippet padrão para um catálogo se houver envios suficientes. Sinta-se livre para continuar enviando built-in para mostrar o poder do seu idioma, mas não hesite em enviar suas respostas não integradas, mesmo que seja muito mais longo e seu idioma não tenha um embutido. Código de golfe feliz no seu idioma favorito!
fonte
-9
aparece na saída?take derivative
emerge
no exponent 1
, embora você não parecem afirmar issoRespostas:
Python 2 ,
252245 bytesExperimente online!
Recebe entrada como uma lista aninhada de coeficientes e termos:
Por exemplo, o primeiro exemplo (
5z-z2y2-5w3y
) é dado como:O rodapé contém uma função que analisa uma string de entrada para o formato de entrada desejado:
parse(s)
.Editar:
fonte
Retina ,
249233 bytesExperimente online! O link inclui casos de teste. Explicação:
Adicione um
_
após cada ocorrência da variável especificada.Divida a entrada em termos.
Mantenha apenas os termos que referenciaram a variável.
Prefixe a
+
se o primeiro termo não tiver um sinal.Classifique cada termo em ordem alfabética. (O sinal corresponde, mas isso não é um problema; ele classifica no início de qualquer maneira.)
Converta todos os expoentes da variável em unário.
Coloque um prefixo temporário 1 para esses termos sem um multiplicador.
Multiplique o multiplicador pelo expoente da variável, deixando o resultado em unário.
Classifique todos os termos.
Adicione termos do mesmo sinal.
Subtrair termos de sinais diferentes.
Remova os termos que foram cancelados por um termo de um sinal diferente.
Converta o multiplicador novamente em decimal.
Decrementar expoentes maiores que três e converter novamente em decimal.
a) Remova um
+
sinal inicial b) Junte todos os termos novamente juntos c) converta quadrados da variável na variável plana d) remova a variável se ela não tiver um expoente.Remova o 1 temporário, a menos que não haja mais nada para multiplicar.
Se não houver termos restantes, o resultado será zero.
O suporte a termos duplicados custa quase metade da minha contagem de bytes. Solução anterior de 123 bytes que não deduplicou os termos:
Experimente online! Explicação:
Adicione um
_
após cada ocorrência da variável especificada.Divida a entrada em termos.
Mantenha apenas os termos que referenciaram a variável.
Converta todos os expoentes da variável em unário.
Coloque um prefixo temporário 1 para esses termos sem um multiplicador.
Multiplique o multiplicador pelo expoente da variável.
Decrementar expoentes maiores que três e converter novamente em decimal.
a) Remova um
+
sinal inicial b) Junte todos os termos novamente juntos c) converta quadrados da variável na variável plana d) remova a variável se ela não tiver um expoente.Remova o 1 temporário, a menos que não haja mais nada para multiplicar.
Se não houver termos restantes, o resultado será zero.
fonte
Wolfram Language (Mathematica) ,
2120 bytes-1 byte graças a Jonathan Frech !
Experimente online!
A entrada é formatada para que todos os termos sejam seguidos
coeff * var1 ^ exp1 * var2 ^ exp2 ...
. Se a entrada pode ser tomado como uma expressão em vez de uma cadeia, a solução é um byte:D
.fonte
#1
pode ser#
.Physica , 3 bytes
Isso não usa nenhum novo recurso.
∂
e sua alternativa somente ASCII,Differentiate
foram introduzidas há mais de 10 dias .Demo
Supõe que a expressão e a variável são passadas como uma sequência. Código de teste:
Saída exata:
Formato de expressão:
*
para multiplicação,**
exponenciação+
e-
adição e subtração de acordo.fonte
Python 3 + SymPy , 23 bytes
Experimente online!
fonte
Pari / GP , 5 bytes
Experimente online!
fonte