Polynomialception


22

f,gTamsayılar üzerinde isteğe bağlı iki polinom verildiğinde , programınız / işleviniz ikinci polinomdaki ilk polinomu değerlendirmelidir. f(g(x))(aka iki polinomun bileşimi (fog)(x) )

ayrıntılar

Yerleşiklere izin verilir. Herhangi bir makul formatı giriş / çıkış olarak kabul edebilirsiniz, ancak giriş ve çıkış formatı aynı olmalıdır. Dize olarak biçimlendirme

x^2+3x+5

veya katsayıların listesi olarak:

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

Ayrıca, giriş polinomlarının tamamen genişletildiği varsayılabilir ve çıkışların da tamamen genişletilmesi beklenir.

Örnekler

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

peki ya yerleşikler?
Maltysen

1
@Maltysen "Detaylar: Yerleşiklere izin verilir. (...)" : D
kusur

2
Bence "herhangi bir makul format" biraz gerilebilir. Polinomu değerlendiren bir fonksiyona izin verilirse, kompozisyon fonksiyonu (.)Haskell'de bir cevaptır. Muhtemelen katsayı listesinin bir temsilini kastediyorsunuzdur.
xnor

1
Başlık! Anladım :-D
Luis Mendo

2
@LuisMendo Hızlı düşünür = P
kusur

Yanıtlar:


10

Haskell, 86 72 bayt

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

Bir fonksiyon tanımlar oböyle o g fbileşim f ∘ g hesaplar. Polinomlar, sabit terimden başlayan boş bir katsayılar listesiyle temsil edilir.

gösteri

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

Nasıl çalışır

Polinomla ilgili yerleşik yapı veya kitaplık yoktur. Benzer nükslere uyun

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

sırasıyla polinom çarpımı ve kompozisyonu için. Her ikisi de forma giriyor

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

Operatör !, zipWith(+).(++[0,0..])polinom eklemesi için kullanarak (ikinci argümanın daha uzun olduğu varsayılarak - amaçlarımız için her zaman olacağı gibi) , U ve C verilen W için bu formun tekrarını çözer . Sonra,

(0:)Polinom argümanını x ile çarpın (sıfır katsayısı hazırlayarak);
(<$>g).(*)polinom tarafından skaler argümanı çoğaltır g;
(0:)!((<$>g).(*))polinom argümanını polinomla çarpar g;
pureskaler bir argümanı sabit bir polinom'a (singleton list) kaldırır;
(0:)!((<$>g).(*))!purePolinom ile bir polinom argümanı oluşturur g.


9

Mathematica, 17 bayt

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

Örnek kullanım:

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 bayt

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

Kullanımı kolaydır, örneğin ilk örnek için:

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

Hangi döner

y^2+5y+9

Girdilerin farklı değişkenlerde olmasını zorunlu kılmak beni aldatıyor gibi görünüyor. Bu cevap için önemli mi?
feersum

Bunu yapmaktan çekinmeyin, açıkça makul herhangi bir uygun giriş biçimine izin verdim.
kusur

Yorumunuzu düzenlemeyle ilgili: evet, fark eder.
kusur

Bu sitedeki kurallara aşina değilim. TI-BASIC'te 1 bayt olması doğru mu?
asmeurer

@ asmeurer Gerçekten: TI-Basic, karşılık gelen hesap makinelerinde kullanılan kodlamayla puanlanır. Ayrıntılarla ilgileniyorsanız, burada meta üzerinde okuyabilirsiniz . Ti-basic-dev'de bir simge tablosu bulunabilir .
kusur

6

Python 2, 138 156 162 bayt

Girişlerin, ilk önce en küçük güçlere sahip tamsayı listeleri olması beklenir.

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

Ungolfed:

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

Bu hesaplamada, polinom katsayıları çok büyük bir tabanda bir sayının rakamları (negatif olabilir) olarak görülür. Polinomlar bu formatta olduktan sonra, çarpma veya ekleme tek bir tamsayı işlemidir. Taban yeterince büyük olduğu sürece, komşu basamaklara dökülen herhangi bir taşıyıcı olmayacaktır.

-18 B@xnor tarafından önerildiği şekilde sınırın iyileştirilmesi.


Güzel yöntem. İçin B, olur 10**len(`a+b`)yeter?
xnor

@xnor Belki ... söylemem zor.
Feersum

+1 Bu gerçekten yaratıcı bir çözüm ve hoş bir bigint kullanımı !!!
kusur

@xnor Şimdi kendimi hte katsayısı uzunluğunun girdi uzunluğunda doğrusal olduğuna ikna etmeyi başardım :)
feersum

5

Python + SymPy, 59 35 bayt

from sympy import*
var('x')
compose

24 byte kapalı golf için @asmeurer teşekkürler!

Test sürüşü

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

1
SymPy'nin bir compose()işlevi var.
asmeurer

1
Cevap nerde? Artık herhangi bir işlevi tanımlamıyor ya da bir şey yapmıyor ...
feersum

1
@ feersum Bu asla böyle olmadı. Bu meta yayını yeni düzenlediniz.
Mego,

3
@feersum Politikaları kendi gündeminize göre değiştirmek için kabul edilmiş bir meta yayını düzenlediniz. Bu iyi değil.
Mego

3
@ feersum İfadelerinizin belirsiz olduğunu düşünmüş olsanız da, açıkça toplumun geri kalanı için değildi. from module import*;functionGeçerli bir başvuru olan oy birliğini kabul ettik . Ne olursa olsun, bu isimlendirilmemiş lambdalarla ithalat ve yardımcı fonksiyonlara izin veren daha yeni bir politikadır.
Mego,

3

Adaçayı, 24 bayt

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

Sage 6.9'dan itibaren ( http://sagecell.sagemath.org sitesinde çalışan sürüm ), işlev açık bir argüman ataması olmadan çağrılar ( f(2) rather than f(x=2)), rahatsız edici ve yararsız bir mesajın STDERR'ye yazdırılmasına neden olur. STDERR golf kodu varsayılan olarak göz ardı edilebildiğinden, bu hala geçerlidir.

Bu çok benzer Dennis'in SymPy cevap Adaçayı Python üzerine inşa edilmiş) bir olduğunu ve b) kullandığı için Maxima , birçok yönden SymPy çok benzer bir bilgisayar cebir sistemi. Ancak, Sage, SymPy ile Python'dan çok daha güçlüdür ve bu nedenle kendi cevabını hak edecek kadar farklı bir dildir.

Tüm test durumlarını çevrimiçi olarak doğrulayın


2

PARI / GP , 19 bayt

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

hangisi yapmana izin veriyor

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

almak

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


1

Sembolik Araç Kutulu MATLAB, 28 bayt

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

Bu anonim bir işlevdir. Aramak için onu bir değişkene atayın veya kullanın ans. Girişler biçiminde dizelerdir (boşluklar isteğe bağlıdır)

x^2 + 3*x + 5

Örnek çalışma:

>> @(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 bayt

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

Bazları kötüye kullanmayan 'uygun' bir uygulama. İlk önce en az anlamlı katsayısı.

apolinom ilavesi, mpolinom çarpımı ve okompozisyondur.


m([c],e(m,[[1]]+[g]*k))aynı değildir e(m,[[c]]+[g]*k)?
Neil,

@Neil İyi çağrı, onunla bir arada iki ezebilirsiniz!
orlp

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

@AndersKaseorg Hakkı ekledim, teşekkürler :)
orlp

Polinom eklemenizi basitleştirmek mümkün olabilir, çünkü bir listenin her zaman diğerinden daha uzun olacağını düşünüyorum, bu yüzden ( or 0)bu sürümde gerek yok .
Neil

1

JavaScript (ES6), 150 103 bayt

(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

Polinomları a = [a 0 , a 1 , a 2 , ...] dizisi olarak kabul eder ve döndürür 0 + a 1 * x + a 2 * x 2 ...

Düzenleme: Özyinelemeden yinelemeli polinom çarpımına geçerek kaydedilen 47 bayt, daha sonra iki mapçağrıyı birleştirmeme izin verdi .

Açıklama: r, boş bir dizi ile temsil edilen, sıfırdan başlar, ve sonuç, bir p olan g h bir başlar. p , her çarpılır f h da, ve sonuç olarak biriken r . p aynı zamanda g ile çarpılır .

(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 + polinom , 41 + 12 = 53 bayt

Bayrak kullanır -rpolynomial. Giriş iki Polynomialnesnedir.

Birisi beni vanilya yakutunda öküyorsa (polinom dış kütüphanesi yok), çok etkileneceğim.

->a,b{i=-1;a.coefs.map{|c|c*b**i+=1}.sum}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.