多项式感知


22

给定两个f,g整数的任意多项式的多项式,您的程序/函数应评估第二个多项式中的第一个多项式。f(g(x))(又名两个多项式的合成 (fog)(x)

细节

允许内置。您可以假定任何合理的格式作为输入/输出,但是输入和输出格式应该匹配。例如格式化为字符串

x^2+3x+5

或作为系数列表:

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

此外,可以假定输入多项式被完全展开,并且期望输出也被完全展开。

例子

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

内建函数呢?
Maltysen '16

1
@Maltysen “详细信息:内置命令允许(......)。” :d
flawr

2
我认为“任何合理的格式”可能都可以扩展。如果允许使用评估多项式的​​函数,则合成函数(.)是Haskell中的答案。您可能是对系数列表的某种表示。
xnor

1
标题!我刚得到它:-D
Luis Mendo

2
@LuisMendo快速思想者= P
缺陷

Answers:


10

Haskell,86 72字节

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

定义一个函数o,以o g f计算合成f∘g。多项式由从常数项开始的非空系数列表表示。

演示版

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

怎么运行的

没有多项式相关的内建函数或库。观察类似的复发

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

分别用于多项式乘法和合成。他们都采取形式

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

!对于给定的U和C,运算符使用W来解决这种形式的重复性,zipWith(+).(++[0,0..])用于多项式加法(假设第二个参数更长,就我们的目的而言,它将始终是)。然后,

(0:)将多项式自变量乘以x(以零系数为前提);
(<$>g).(*)将标量参数乘以多项式g;
(0:)!((<$>g).(*))用多项式乘以多项式参数g;
pure将标量参数提升为常数多项式(单子列表);
(0:)!((<$>g).(*))!pure用多项式组成一个多项式参数g


9

Mathematica,17个字节

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

用法示例:

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个字节

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

用法很简单,例如第一个示例:

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

哪个返回

y^2+5y+9

对我来说,要求输入具有不同的变量似乎是一种欺骗。这个答案有关系吗?
feersum '16

请随意,我明确允许使用任何合理且方便的输入格式。
瑕疵的2016年

关于您的评论的编辑:是的,这很重要。
瑕疵的2016年

我不太熟悉此站点上的规则。在TI-BASIC中为1字节是否正确?
asmeurer

@asmeurer确实:TI-Basic是由相应计算器上使用的编码评分的。如果您对这些细节感兴趣,可以在meta上阅读。可以在ti-basic-dev上找到令牌表。
瑕疵的2016年

6

Python 2,138156162字节

输入应该是最小功率的整数列表。

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

取消高尔夫:

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

在此计算中,多项式系数被视为非常大的基数中的数字(可能为负)。多项式采用这种格式后,乘法或加法就是一个整数运算。只要基数足够大,就不会有任何溢出到相邻数字的进位。

从-18提高结合在B由@xnor的建议。


不错的方法。对于B,就10**len(`a+b`)足够了吗?
xnor

@xnor也许...我很难告诉。
feersum '16

+1这是一个非常有创意的解决方案,并且可以很好地使用bigints !!!
瑕疵的2016年

@xnor现在,我已经设法说服自己,系数长度在输入长度中是线性的:)
feersum 2016年

5

Python + SymPy,59个 35字节

from sympy import*
var('x')
compose

感谢@asmeurer打高尔夫球24个字节!

测试运行

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

1
SymPy具有compose()功能。
asmeurer

1
答案在哪里?它不再定义任何功能或执行任何操作……
feersum 2016年

1
@feersum从来没有这样。您刚刚编辑了该元信息。
Mego 2016年

3
@feersum您编辑了一个可接受的元帖子,以修改自己的议程政策。那不行
Mego

3
@feersum尽管您可能认为自己的措词含糊不清,但显然不适合社区其他成员。我们接受from module import*;function了有效的共识。无论如何,是更新的策略,该策略允许使用未命名的lambda导入和帮助函数。
Mego

3

Sage,24个字节

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

从Sage 6.9(运行在http://sagecell.sagemath.org上的版本)开始,没有显式参数分配(f(2) rather than f(x=2))的函数调用会导致将烦人且无益的消息打印到STDERR。因为默认情况下在代码高尔夫中可以忽略STDERR,所以这仍然有效。

这与Dennis的SymPy答案非常相似,因为Sage是a)基于Python构建的,并且b)使用Maxima(一种在许多方面与SymPy非常相似的计算机代数系统)。但是,Sage比带有SymPy的Python强大得多,因此是一种足够不同的语言,值得您自己回答。

在线验证所有测试用例


2

PARI / GP,19字节

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

这可以让你做

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

要得到

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


1

带符号工具箱的MATLAB,28个字节

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

这是一个匿名函数。要调用它,请将其分配给变量或使用ans。输入是具有以下格式的字符串(空格是可选的)

x^2 + 3*x + 5

示例运行:

>> @(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字节

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

不滥用基础的“适当”实施。最低有效系数在前。

a是多项式加法,m是多项式乘法,并且o是组合。


m([c],e(m,[[1]]+[g]*k))不是一样e(m,[[c]]+[g]*k)
尼尔

@Neil好的电话,可以用它来二合一!
orlp

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

@AndersKaseorg对,我添加了它,谢谢:)
orlp

可能可以简化多项式加法运算,因为我认为一个列表总是比另一个列表长,因此( or 0)在该版本中不需要。
尼尔

1

的JavaScript(ES6),150个 103字节

(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

接受并返回多项式作为数组a = [a 0,a 1,a 2,...],该数组表示a 0 + a 1 * x + a 2 * x 2 ...

编辑:通过从递归多项式切换到迭代多项式乘法,节省了47个字节,然后允许我合并两个map调用。

说明:r是结果,从零开始,由一个空数组表示,而pg h,从一开始。p依次乘以每个f h,结果累加到r中p也同时乘以g

(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 + 多项式,41 + 12 = 53字节

使用标志-rpolynomial。输入是两个Polynomial对象。

如果有人在香草Ruby(没有多项式外部库)中超越我,我会留下深刻的印象。

->a,b{i=-1;a.coefs.map{|c|c*b**i+=1}.sum}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.