计算特定值的多项式的第n个迭代;fⁿ(x)


19

给定一个多项式函数f(例如,作为实数系数的列表p升序或降序),一个非负整数n和一个实数值x,返回:

   f nx

即值˚F˚F˚F(... ˚FX)...))),用于Ñ的应用˚FX

使用合理的精度和舍入。

f作为系数列表的解决方案可能是最有趣的,但是如果您能够将f作为实际函数(从而将此挑战减少为琐碎的“ n次应用函数”),请随时添加非平凡的解决方案之后。

案例案例

p  = [1,0,0]f  = x^2,  n  = 0,  x  = 3:  f 0(3)=3

p  = [1,0,0]f  = x^2,  n  = 1,  x  = 3:  f 1(3)=9

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 0,  x  = 2.3:  f 0(2.3)=2.3

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 1,  x  = 2.3:  f 1(2.3)=-8.761

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 2,  x  = 2.3:  f 2(2.3)=23.8258

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 3,  x  = 2.3:  f 3(2.3)=-2.03244

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 4,  x  = 2.3:  f 4(2.3)=1.08768

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 5,  x  = 2.3:  f 5(2.3)=-6.38336

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 6,  x  = 2.3:  f 6(2.3)=14.7565

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 7,  x  = 2.3:  f 7(2.3)=-16.1645

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 8,  x  = 2.3:  f 8(2.3)=59.3077

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 9,  x  = 2.3:  f 9(2.3)=211.333

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 10,  x  = 2.3:  f 10(2.3)=3976.08

p  = [0.1,-2.3,-4]f  = 0.1x^2-2.3x-4,  n  = 11,  x  = 2.3:  f 11(2.3)=1571775

p  = [-0.1,2.3,4]f  = −0.1x^2+2.3x+4,  n  = 0,  x  = -1.1:  f 0(-1.1)=-1.1

p  = [-0.1,2.3,4]f  = −0.1x^2+2.3x+4,  n  = 1,  x  = -1.1:  f 1(-1.1)=1.349

p  = [-0.1,2.3,4]f  = −0.1x^2+2.3x+4,  n  = 2,  x  = -1.1:  f 2(-1.1)=6.92072

p  = [-0.1,2.3,4]f  = −0.1x^2+2.3x+4,  n  = 14,  x  = -1.1:  f 14(-1.1)=15.6131

p  = [0.02,0,0,0,-0.05]f  = 0.02x^4-0.05,  n  = 25,  x  = 0.1:  f 25(0.1)=-0.0499999

p  = [0.02,0,-0.01,0,-0.05]f  = 0.02x^4-0.01x^2-0.05,  n  = 100,  x  = 0.1:  f 100(0.1)=-0.0500249



例如,我的果冻答案可以采用果冻链接并将其视为“功能”吗?
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer我最初需要输入作为系数列表,以防止出现这种琐碎的解决方案。但是,我应要求放松了。我建议您发布列表版本,并将普通版本添加为注释(或相反)。
2015年

我已经发布了列表版本,但是功能版本要短得多。
暴民埃里克(Erik the Outgolfer)

@EriktheOutgolfer是的,显然。参见我添加的注释。
亚当

Answers:


7

八度,49字节

@(p,x,n)(f=@(r,m){@()p(r(r,m-1)),x}{~m+1}())(f,n)

在线尝试!

或者,取系数:

八度75 57字节

@(p,x,n)(f=@(f,n){@()polyval(p,f(f,n-1)),x}{~n+1}())(f,n)

在线尝试!

特别感谢Suever在StackOverflow 上为我的一个问题回答了这个问题,这证明了递归匿名函数是可能的。

这定义了一个匿名函数,它是递归匿名函数的包装;这不是本地的Octave概念,而是需要一些新的单元阵列索引。

另外,第二个版本是Octave变量作用域中的一个很好的课程。的所有实例都r可以合法替换为f,然后直接覆盖f最本地范围内的现有实例(与相似n

说明

@(p,x,n)(f=@(r,m){@()p(r(r,m-1)),x}{~m+1}())(f,n)
@(p,x,n)         .                ..    .  ..   .   % Defines main anonymous function    
        (f=@(r,m).                ..    .  ).   .   % Defines recursive anonymous function
                 .                ..    .   .   .   %  r: Handle ('pointer') to recursive function
                 .                ..    .   .   .   %  m: Current recursion depth (counting from n to 0)
                 .                ..    .   (f,n)   % And call it, with
                 .                ..    .           %  r=f (handle to itself)
                 .                ..    .           %  m=n (initial recursion)
                 {                }{    }           % Create and index into cell array
                                    ~m+1            %  Index: for m>0: 1; for m==0: 2.
                                ,x                  %  Index 2: final recursion, just return x.
                  @()                               %  Index 1: define anonymous function, taking no inputs.
                     p(        )                    %   which evaluates the polynomial 
                       r(     )                     %    of the recursive function call
                         r,m-1                      %     which is called with r 
                                                    %     and recursion depth m-1 
                                                    %     (until m=0, see above)
                                         ()         % Evaluate the result of the cell array indexing operation.
                                                    %  which is either the anonymous function
                                                    %  or the constant `x`.

这样做的关键是定义匿名函数时对其进行评估。因此,,@()实际上似乎是多余的,因为它定义了一个()直接在其后调用的匿名函数,实际上是绝对必要的。除非由索引语句选择它,否则不调用它。

八度,39字节(无聊)

function x=f(p,x,n)for i=1:n;o=p(o);end

出于完整性考虑,字节数最短的Octave解决方案。 打哈欠。


我会尝试再次阅读,但是我还是不太明白。作为八度音阶的忠实粉丝,我只能说,出色的+1。
Michthan

2
@Michthan我会尝试做出更好的解释,但这是我编写的迄今为止最简洁的Octave-通常,函数名是字节数的主要部分。差不多是Lisp。
桑奇斯

1
@Michthan希望新的解释有一定的道理,以“爆炸”的观点来看。
桑奇斯

4

Mathematica,56 47 28字节

Nest[x\[Function]x#+#2&~Fold~#,##2]&

\[Function] 在UTF-8中占用3个字节。

按顺序获取参数p,x,n

p (参数1)的顺序递增。

显然,如果f可以将其视为函数,则可以简化为Nest


您需要反转系数吗?
朱塞佩

@Giuseppe这就是为什么Reverse在代码中。
user202729

@ user202729我认为您可以按照想要的任何顺序(升序或降序)获取系数。
暴民埃里克(Erik the Outgolfer)

我相信,我们可以按照升序或降序来接受它们。(我一点也不了解Mathematica)
朱塞佩(Giuseppe

是的,你可以可以把他们在需要的顺序:升序或降序排列
亚当

4

外壳,5个字节

←↓¡`B

在线尝试!

此处的关键思想是,在点x处评估一个策略等效于从基数x执行基数转换。

B给定基数和数字列表时,将执行基数转换。在这里,我们使用其翻转版本,以便首先获取数字列表并将部分功能应用于此列表。然后,我们获得一个函数,该函数在某个点计算给定多项式的值,该解决方案的第二部分处理此函数的正确迭代次数:

外壳,3个字节

←↓¡

¡ 是“迭代”函数,它需要一个函数和一个起点,并返回迭代该函数获得的无限值列表。

接受一个数字(此挑战的第三个参数),并从列表的开头删除那么多元素。

返回结果列表的第一个元素。



3

Ruby,42个字节

->c,n,x{n.times{x=c.reduce{|s,r|s*x+r}};x}

C是降序系数列表

平凡的版本,其中f是lambda函数(26个字节):

->f,n,x{n.times{x=f[x]};x}

# For example:
# g=->f,n,x{n.times{x=f[x]};x}
# p g[->x{0.02*x**4-0.01*x**2-0.05},100,0.1]

在线尝试!


3

JavaScript(ES6), 52 49 44  42字节

多亏了GB,节省了5个字节,而多亏了尼尔,节省了2个字节

以currying语法输入为(p)(n)(x),其中p是降序系数列表。

p=>n=>g=x=>n--?g(p.reduce((s,v)=>s*x+v)):x

测试用例


如果p降序排列,则可以使用s * x + v减少并忽略i。
GB

在这种情况下,您可以省略,0减少吗?
尼尔,

@Neil好抓住。:-)
Arnauld

2

J,15个字节

0{(p.{.)^:(]{:)

在线尝试!

将多项式作为升幂系数的列表。

说明

0{(p.{.)^:(]{:)  Input: polynomial P (LHS), [x, n] (RHS)
            {:   Tail of [x, n], gets n
           ]     Right identity, passes n
  (    )^:       Repeat n times starting with g = [x, n]
     {.            Head of g
   p.              Evaluate P at that value
                   Return g = [P(head(g))]
0{               Return the value at index 0

2

05AB1E10 9字节

-1个字节感谢外长者埃里克(Erik the Outgolfer)

sF³gݨm*O

在线尝试!

以x为第一个参数,n为第二个参数,p以升序排列为第三个参数。

说明

sF³gݨm*O
s         # Forces the top two input arguments to get pushed and swaped on the stack
 F        # Do n times...
  ³        # Push the third input (the coefficients)
   g       # Get the length of that array...
    ݨ     # and create the range [0 ... length]
      m    # Take the result of the last iteration to these powers (it's just x for the first iteration)
       *   # Multiply the resuling array with the corresponding coefficients
         O # Sum the contents of the array
          # Implicit print

1
您可以删除第二个³
暴民埃里克(Erik the Outgolfer)'17年

同样(This is in case n is 0 so x is on the stack)是错误的,您仍然需要s非零的n。
暴民埃里克(Erik the Outgolfer)'17年

对,是真的。我正沿着更换的线条更加的思维¹²。随着s因此它的推X在1个字节进行堆栈没有至少需要循环一次的工作。可能应该说的更好,^^'。还要感谢-1!
Datboi

我的意思是您将仍然需要它,因为05AB1E如果已读取所有输入,则将最后一个输入用于隐式输入。
暴民埃里克(Erik the Outgolfer)

sF³gݨm³O以及解释中的内容…
暴民埃里克(Erik the Outgolfer)'17

2

Haskell,15个字节

((!!).).iterate

在线尝试!

归功于全人类为这两种解决方案节省了11个字节

这定义了一个默认函数,该函数将一个函数作为其第一个自变量和n第二个自变量,并与自身n时间一起构成该函数。然后可以使用参数调用该函数x以获得最终值。多亏了curring的魔力,这等效于一个带有三个参数的函数。


取系数列表而不是函数参数:

Haskell,53个字节

((!!).).iterate.(\p x->sum$zipWith(*)p[x^i|i<-[0..]])

在线尝试!

这与上面的代码相同,但是由一个lambda函数组成,该函数将一系列系数转换为多项式函数。系数从示例中以相反的顺序获取-的升序x



第二个的TIO应该采取一个列表作为参数,而不是一个函数)虽然你可以使用折叠状保存字节屈指可数(注意,零多项式不能[],但必须是这样的[0]或类似的)。
ბიმო

2

APL(Dyalog)20 9字节

{⊥∘⍵⍣⎕⊢⍺}

在线尝试!

x函数的系数取为左引数,函数的系数取为右引数,n取自STDIN。

经过很长一段时间的回顾,我意识到我可以通过使用base conversion简化计算


APL(Dyalog),5个字节

如果我们可以将该函数用作Dyalog APL函数,则可以为5个字节。

⎕⍣⎕⊢⎕

xn然后将该功能作为来自STDIN的输入。


2

R96 58 55 52字节

f=function(n,p,x)`if`(n,f(n-1,p,x^(seq(p)-1)%*%p),x)

在线尝试!

说明:

seq(p)1, 2, ..., length(p)p为向量时生成列表,因此seq(p)-1多项式的指数也是如此,因此x^(seq(p)-1)等于x^0(始终等于1), x^1, x^2, ...并计算点乘积%*%p并在处计算多项式x

此外,如果P将其作为函数使用,则将为38个字节:

function(n,P,x)`if`(n,f(n-1,P,P(x)),x)

当然,我们总是可以P通过P=function(a)function(x)sum(x^(seq(a)-1)*a)



1

Python 3中70 69个字节

f=lambda p,n,x:n and f(p,n-1,sum(c*x**i for i,c in enumerate(p)))or x

采用p升序,即如果p是,[0, 1, 2]则对应的多项式为p(x) = 0 + 1*x + 2*x^2。简单的递归解决方案。

在线尝试!


1

C#(.NET Core),82字节

using System.Linq;f=(p,n,x)=>n<1?x:p.Select((c,i)=>c*Math.Pow(f(p,n-1,x),i)).Sum()

在线尝试!

以与测试用例相反的顺序(递增顺序?)获取系数列表,以使它们在数组中的索引等于x的幂次。

普通版本的30个字节:

f=(p,n,x)=>n<1?x:f(p,n-1,p(x))

在线尝试!

接受一个委托并将其递归应用n次。


1

MATL,11个字节

ii:"ZQ6Mw]&

在线尝试!

虽然我认为有一些巧妙的输入方法可以确保n=0按预期工作,但它的趣味性比我的Octave回答略有趣。


1

朱莉娅0.6.0(78字节)

using Polynomials;g(a,n,x)=(p=Poly(a);(n>0&&(return g(a,n-1,p(x)))||return x))

说明:

多项式很容易说明:它创建多项式。之后,这是一个非常基本的递归。

为了具有多项式:-4.0-2.3 * x + 0.1 * x ^ 2输入a必须类似于a = [-4, -2.3, 0.1]


1

公理,91字节

f(n,g,x)==(for i in 1..n repeat(v:=1;r:=0;for j in 1..#g repeat(r:=r+v*g.j;v:=v*x);x:=r);x)

缩进

fn(n,g,x)==
     for i in 1..n repeat
          v:=1; r:=0
          for j in 1..#g repeat(r:=r+v*g.j;v:=v*x)
          x:=r
     x

多项式g的输入是与练习示例相反的一个数字列表。例如

[1,2,3,4,5]  

这将代表政治

1+2*x+3*x^2+4*x^3+5*x^4

测试:

(3) -> f(0,[0,0,1],3)
   (3)  3
                                                    Type: PositiveInteger
(4) -> f(1,[0,0,1],3)
   (4)  9
                                                    Type: PositiveInteger
(5) -> f(0,[-4,-2.30,0.1],2.3)
   (5)  2.3
                                                              Type: Float
(6) -> f(1,[-4,-2.30,0.1],2.3)
   (6)  - 8.7610000000 000000001
                                                              Type: Float
(7) -> f(2,[-4,-2.30,0.1],2.3)
   (7)  23.8258121
                                                              Type: Float
(8) -> f(9,[-4,-2.30,0.1],2.3)
   (8)  211.3326335688 2052491
                                                              Type: Float
(9) -> f(9,[-4,-2.30,0.1,0,0,0,0,1],2.3)
   (9)  0.4224800431 1790652974 E 14531759
                                                              Type: Float
                                   Time: 0.03 (EV) + 0.12 (OT) = 0.15 sec
(10) -> f(2,[-4,-2.30,0.1,0,0,0,0,1],2.3)
   (10)  44199336 8495528344.36
                                                              Type: Float


1

C ++ 14,71个字节

作为通用的未命名lambda,通过xParameter 返回:

[](auto C,int n,auto&x){for(auto t=x;t=0,n--;x=t)for(auto a:C)t=a+x*t;}

取消测试和测试用例:

#include<iostream>
#include<vector>

using namespace std;

auto f=
[](auto C,int n,auto&x){
 for(
  auto t=x; //init temporary to same type as x
  t=0, n--; //=0 at loop start, also check n
  x=t       //apply the result
  )
  for(auto a:C)
   t=a+x*t; //Horner-Scheme
}
;


int main() {
 vector<double> C = {0.1,-2.3,-4};//{1,0,0};
 for (int i = 0; i < 10; ++i) {
  double x=2.3;
  f(C, i, x);
  cout << i << ": " << x << endl;
 }
}

0

QBIC,19个字节

[:|:=:*c^2+:*c+:}?c

将输入作为

  • 迭代次数
  • x的起始值
  • 然后是多项式的3个部分

样本输出:

Command line: 8 2.3 0.1 -2.3 -4
 59.30772

0

Clojure,66个字节

#(nth(iterate(fn[v](apply +(map *(iterate(partial * v)1)%3)))%2)%)

完整示例:

(def f #(nth(iterate(fn[v](apply +(map *(iterate(partial * v)1)%3)))%2)%))
(f 10 2.3 [-4 -2.3 0.1])
; 3976.0831439050253

组成一个函数为26个字节:

#(apply comp(repeat % %2))

(def f #(apply comp(repeat % %2)))
((f 10 #(apply + (map * [-4 -2.3 0.1] (iterate (partial * %) 1)))) 2.3)
; 3976.0831439050253

0

Japt,18个字节

很简单,挑战在罐子上说了什么。

o r_VË*ZpVÊ-EÉÃx}W
o                  // Take `n` and turn it into a range [0,n).
  r_            }W // Reduce over the range with initial value of `x`.
    VË             // On each iteration, map over `p`, yielding the item
      *Z           // times the current reduced value
        pVÊ-EÉ     // to the correct power,
              Ãx   // returning the sum of the results.

注意到为了输入npx

在线尝试!

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.