Polynomialception


22

Étant donné deux polynômes f,gde degré arbitraire sur les entiers, votre programme / fonction doit évaluer le premier polynôme du deuxième polynôme. f(g(x))(alias la composition (fog)(x) des deux polynômes)

Détails

Les Builtins sont autorisés. Vous pouvez assumer toute mise en forme raisonnable comme entrée / sortie, mais le format d'entrée et de sortie doit correspondre. Par exemple, formatage sous forme de chaîne

x^2+3x+5

ou comme liste de coefficients:

[1,3,5] or alternatively [5,3,1]

De plus, les polynômes d'entrée peuvent être supposés être entièrement développés, et les sorties devraient également être complètement développées.

Exemples

A(x) = x^2 + 3x + 5, B(y) = y+1
A(B(y)) = (y+1)^2 + 3(y+1) + 5 = y^2 + 5y + 9

A(x) = x^6 + x^2 + 1, B(y) = y^2 - y
A(B(y))= y^12 - 6y^11 + 15y^10 - 20y^9 + 15y^8 - 6y^7 + y^6 + y^4 - 2 y^3 + y^2 + 1

A(x) = 24x^3 - 144x^2 + 288x - 192, B(y) = y + 2
A(B(y)) = 24y^3

A(x) = 3x^4 - 36x^3 + 138x^2 - 180x + 27, B(y) = 2y + 3
A(B(y)) = 48y^4 - 96y^2

qu'en est-il des builtins?
Maltysen

1
@Maltysen "Détails: Les buildins sont autorisés. (...)" : D
flawr

2
Je pense que "n'importe quel format raisonnable" pourrait être un peu extensible. Si une fonction qui évalue le polynôme est autorisée, alors la fonction de composition (.)est une réponse dans Haskell. Vous voulez probablement dire une représentation de la liste des coefficients.
xnor

1
Le titre! Je viens de le recevoir :-D
Luis Mendo

2
@LuisMendo Quick thinker = P
flawr

Réponses:


10

Haskell, 86 72 octets

u!c=foldr1((.u).zipWith(+).(++[0,0..])).map c
o g=(0:)!((<$>g).(*))!pure

Définit une fonction otelle que o g fcalcule la composition f ∘ g. Les polynômes sont représentés par une liste non vide de coefficients commençant au terme constant.

Démo

*Main> o [1,1] [5,3,1]
[9,5,1]
*Main> o [0,-1,1] [1,0,1,0,0,0,1]
[1,0,1,-2,1,0,1,-6,15,-20,15,-6,1]
*Main> o [2,1] [-192,288,-144,24]
[0,0,0,24]
*Main> o [3,2] [27,-180,138,-36,3]
[0,0,-96,0,48]

Comment ça marche

Pas de bibliothèques ou de programmes intégrés liés aux polynômes. Observez les récidives similaires

f (x) = a + f₁ (x) x ⇒ f (x) g (x) = ag (x) + f₁ (x) g (x) x,
f (x) = a + f₁ (x) x ⇒ f (g (x)) = a + f₁ (g (x)) g (x),

pour la multiplication et la composition polynomiales, respectivement. Ils prennent tous les deux la forme

f (x) = a + f₁ (x) x ⇒ W (f) (x) = C (a) (x) + U (W (f₁)) (x).

L'opérateur !résout une récurrence de cette forme pour W étant donné U et C, en utilisant zipWith(+).(++[0,0..])pour l'addition polynomiale (en supposant que le deuxième argument est plus long - pour nos besoins, il le sera toujours). Ensuite,

(0:)multiplie un argument polynomial par x (en ajoutant un coefficient nul);
(<$>g).(*)multiplie un argument scalaire par le polynôme g;
(0:)!((<$>g).(*))multiplie un argument polynomial par le polynôme g;
purelève un argument scalaire en un polynôme constant (liste singleton);
(0:)!((<$>g).(*))!purecompose un argument polynomial avec le polynôme g.


9

Mathematica, 17 octets

Expand[#/.x->#2]&

Exemple d'utilisation:

In[17]:= Expand[#/.x->#2]& [27 - 180x + 138x^2 - 36x^3 + 3x^4, 3 + 2x]

              2       4
Out[17]= -96 x  + 48 x

7

TI-Basic 68k, 12 octets

a|x=b→f(a,b)

L'utilisation est simple, par exemple pour le premier exemple:

f(x^2+3x+5,y+1)

Qui revient

y^2+5y+9

Il semble que je triche d'exiger que les entrées soient dans des variables différentes. Est-ce important pour cette réponse?
feersum

N'hésitez pas à le faire, j'ai explicitement autorisé tout format d'entrée pratique raisonnable.
flawr

Concernant la modification de votre commentaire: oui c'est important.
flawr

Je ne connais pas trop les règles de ce site. Est-il correct d'avoir 1 octet dans TI-BASIC?
asmeurer

@asmeurer En effet: TI-Basic est noté par l'encodage utilisé sur les calculatrices correspondantes. Si vous êtes intéressé par les détails, vous pouvez le lire ici sur meta . Un tableau des jetons peut être trouvé ici sur ti-basic-dev .
flawr

6

Python 2, 138 156 162 octets

Les entrées devraient être des listes entières avec les plus petites puissances en premier.

def c(a,b):
 g=lambda p,q:q>[]and q[0]+p*g(p,q[1:]);B=99**len(`a+b`);s=g(g(B,b),a);o=[]
 while s:o+=(s+B/2)%B-B/2,;s=(s-o[-1])/B
 return o

Non golfé:

def c(a,b):
 B=sum(map(abs,a+b))**len(a+b)**2
 w=sum(B**i*x for i,x in enumerate(b))
 s=sum(w**i*x for i,x in enumerate(a))
 o=[]
 while s:o+=min(s%B,s%B-B,key=abs),; s=(s-o[-1])/B
 return o

Dans ce calcul, les coefficients polynomiaux sont considérés comme des chiffres (qui peuvent être négatifs) d'un nombre dans une très grande base. Une fois les polynômes dans ce format, la multiplication ou l'addition est une opération à un seul entier. Tant que la base est suffisamment grande, il n'y aura aucun report qui se répandra dans les chiffres voisins.

-18 de l'amélioration liée Bcomme suggéré par @xnor.


Belle méthode. Car B, serait- 10**len(`a+b`)ce suffisant?
2016

@xnor Peut-être ... c'est difficile à dire pour moi.
feersum

+1 C'est une solution vraiment créative et une belle utilisation des bigints !!!
flawr

@xnor Maintenant, j'ai réussi à me convaincre que la longueur du coefficient hte est linéaire dans la longueur d'entrée :)
feersum

5

Python + SymPy, 59 35 octets

from sympy import*
var('x')
compose

Merci à @asmeurer d'avoir joué au golf 24 octets!

Essai

>>> from sympy import*
>>> var('x')
x
>>> f = compose
>>> f(x**2 + 3*x + 5, x + 1)
x**2 + 5*x + 9

1
SymPy a une compose()fonction.
asmeurer du

1
Où est la réponse? Il ne définit plus aucune fonction ou ne fait rien ...
feersum

1
@feersum Cela n'a jamais été le cas. Vous venez de modifier cette méta-publication.
Mego

3
@feersum Vous avez modifié une méta publication acceptée pour modifier la politique de votre propre agenda. Ce n'est pas ok.
Mego

3
@feersum Bien que vous ayez pu penser que votre libellé était ambigu, ce n'était clairement pas pour le reste de la communauté. Nous avons accepté le consensus qui from module import*;functionétait une soumission valable. Quoi qu'il en soit, il s'agit d'une politique plus récente, qui autorise les importations et les fonctions d'assistance avec des lambdas sans nom.
Mego

3

Sauge, 24 octets

lambda A,B:A(B).expand()

Depuis Sage 6.9 (la version qui s'exécute sur http://sagecell.sagemath.org ), les appels de fonction sans affectation d'argument explicite (f(2) rather than f(x=2) ) provoquent l'impression d'un message ennuyeux et inutile sur STDERR. Parce que STDERR peut être ignoré par défaut dans le code golf, cela est toujours valide.

Ceci est très similaire à la réponse SymPy de Dennis parce que Sage est a) construit sur Python et b) utilise Maxima , un système d'algèbre informatique très similaire à SymPy à bien des égards. Cependant, Sage est beaucoup plus puissant que Python avec SymPy, et est donc un langage suffisamment différent pour qu'il mérite sa propre réponse.

Vérifiez tous les cas de test en ligne


2

PARI / GP , 19 octets

(a,b)->subst(a,x,b)

ce qui vous permet de faire

%(x^2+1,x^2+x-1)

obtenir

% 2 = x ^ 4 + 2 * x ^ 3 - x ^ 2 - 2 * x + 2


1

MATLAB avec Symbolic Toolbox, 28 octets

@(f,g)collect(subs(f,'x',g))

Il s'agit d'une fonction anonyme. Pour l'appeler, affectez-le à une variable ou utilisez ans. Les entrées sont des chaînes au format (les espaces sont facultatifs)

x^2 + 3*x + 5

Exemple d'exécution:

>> @(f,g)collect(subs(f,'x',g))
ans = 
    @(f,g)collect(subs(f,'x',g))
>> ans('3*x^4 - 36*x^3 + 138*x^2 - 180*x + 27','2*x + 3')
ans =
48*x^4 - 96*x^2

1

Python 2, 239 232 223 octets

r=range
e=reduce
a=lambda*l:map(lambda x,y:(x or 0)+(y or 0),*l)
m=lambda p,q:[sum((p+k*[0])[i]*(q+k*[0])[k-i]for i in r(k+1))for k in r(len(p+q)-1)]
o=lambda f,g:e(a,[e(m,[[c]]+[g]*k)for k,c in enumerate(f)])

Une mise en œuvre «correcte» qui n'abuse pas des bases. Coefficient le moins significatif en premier.

aest l'addition mpolynomiale, la multiplication polynomiale et la ocomposition.


N'est-ce m([c],e(m,[[1]]+[g]*k))pas la même chose que e(m,[[c]]+[g]*k)?
Neil

@Neil Bon appel, peut écraser deux en un avec ça!
orlp

a=lambda*l:map(lambda x,y:(x or 0)+(y or 0),*l)
Anders Kaseorg

@AndersKaseorg À droite, je l'ai ajouté, merci :)
orlp

Il pourrait être possible de simplifier votre ajout de polynômes, car je pense qu'une liste sera toujours plus longue que l'autre, vous n'avez donc pas besoin de ( or 0)dans cette version.
Neil

1

JavaScript (ES6), 150 103 octets

(f,g)=>f.map(n=>r=p.map((m,i)=>(g.map((n,j)=>p[j+=i]=m*n+(p[j]||0)),m*n+(r[i]||0)),p=[]),r=[],p=[1])&&r

Accepte et renvoie les polynômes sous forme de tableau a = [a 0 , a 1 , a 2 , ...] qui représente un 0 + a 1 * x + a 2 * x 2 ...

Edit: sauvé 47 octets en passant de la multiplication polynomiale récursive à itérative, ce qui m'a ensuite permis de fusionner deux map appels.

Explication: r est le résultat, qui commence à zéro, représenté par un tableau vide, et p est g h , qui commence à un. p est multiplié par chaque f h à son tour, et le résultat accumulé dans r . p est également multiplié par g en même temps.

(f,g)=>f.map(n=>            Loop through each term of f (n = f[h])
 r=p.map((m,i)=>(           Loop through each term of p (m = p[i])
  g.map((n,j)=>             Loop though each term of g (n = g[j])
   p[j+=i]=m*n+(p[j]||0)),  Accumulate p*g in p
  m*n+(r[i]||0)),           Meanwhile add p[i]*f[h] to r[i]
  p=[]),                    Reset p to 0 each loop to calculate p*g
 r=[],                      Initialise r to 0
 p=[1]                      Initialise p to 1
)&&r                        Return the result


1

Ruby 2,4 + polynôme , 41 + 12 = 53 octets

Utilise le drapeau -rpolynomial. L'entrée est deux Polynomialobjets.

Si quelqu'un me surpasse en Ruby vanille (pas de bibliothèque externe polynomiale), je serai très impressionné.

->a,b{i=-1;a.coefs.map{|c|c*b**i+=1}.sum}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.