Hitung iterate ke-n dari polinomial untuk nilai tertentu; fⁿ (x)


19

Diberikan fungsi polinom f (misalnya sebagai daftar p dari koefisien nyata dalam urutan naik atau turun), bilangan bulat n -negatif , dan nilai riil x , mengembalikan:

   f n ( x )

yaitu nilai f ( f ( f (... f ( x ) ...))) untuk aplikasi n dari f pada x .

Gunakan presisi dan pembulatan yang wajar.

Solusi yang mengambil f sebagai daftar koefisien mungkin akan menjadi yang paling menarik, tetapi jika Anda dapat menganggap f sebagai fungsi aktual (dengan demikian mengurangi tantangan ini menjadi sepele "menerapkan fungsi n kali"), jangan ragu untuk memasukkannya setelah solusi non-sepele Anda.

Contoh kasus

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

p  = [-0.1,2.3,4]atau 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]atau 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]atau f  = 0.02x^4-0.01x^2-0.05,  n  = 100,  x  = 0.1:  f 100 (0.1) =-0.0500249



Bisakah Jelly saya menjawab mengambil tautan Jelly dan menganggapnya sebagai "fungsi", misalnya?
Erik the Outgolfer

@EriktheOutgolfer Saya awalnya memerlukan input sebagai daftar koefisien untuk mencegah solusi sepele seperti itu. Namun, saya santai dengan permintaan. Saya sarankan Anda memposting versi daftar, dan menambahkan versi sepele sebagai catatan (atau sebaliknya).
Adám

Saya sudah memposting versi daftar, tetapi versi fungsinya jauh lebih pendek.
Erik the Outgolfer

@EriktheOutgolfer Ya, jelas. Lihat catatan saya yang ditambahkan.
Adám

Jawaban:


7

Oktaf , 49 byte

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

Cobalah online!

Atau, dengan mengambil koefisien:

Oktaf , 75 57 byte

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

Cobalah online!

Terima kasih khusus untuk Suever di StackOverflow, untuk jawaban ini beberapa waktu yang lalu pada pertanyaan saya, membuktikan bahwa fungsi anonim rekursif dimungkinkan.

Ini mendefinisikan fungsi anonim, yang merupakan pembungkus untuk fungsi anonim rekursif ; sesuatu yang bukan konsep Octave asli, dan memerlukan beberapa pengindeksan array sel mewah.

Sebagai bonus, versi kedua adalah pelajaran yang bagus dalam pelingkupan variabel dalam Oktaf. Semua contoh dari rsecara legal dapat diganti oleh f, yang kemudian hanya menimpa yang ada fdi ruang lingkup paling lokal (serupa untuk n)

Penjelasan

@(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`.

Kunci untuk ini adalah bahwa fungsi anonim tidak dievaluasi ketika mereka didefinisikan. Jadi, yang @(), agak berlebihan karena mendefinisikan fungsi anonim yang dipanggil ()langsung setelahnya, sebenarnya sangat diperlukan. Itu tidak dipanggil kecuali dipilih oleh pernyataan pengindeksan.

Oktaf , 39 byte (cara membosankan)

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

Hanya untuk kelengkapan, solusi Oktaf dengan bytecount terpendek. Menguap. .


Saya akan mencoba membaca ulang ini lain kali, tapi saya masih belum mengerti .. Sebagai penggemar Oktaf saya hanya bisa mengatakan, pekerjaan yang bagus +1.
Michthan

2
@Michthan saya akan mencoba dan membuat penjelasan yang lebih baik, tetapi sejauh ini Oktaf yang paling singkat yang saya tulis - biasanya, nama fungsi adalah mayoritas dari jumlah byte. Itu hampir Ganjil.
Sanchises

1
@Michthan Semoga penjelasan baru ini masuk akal, melihatnya dalam pandangan 'meledak'.
Sanchises

4

Mathematica, 56 47 28 byte

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

\[Function] membutuhkan 3 byte dalam UTF-8.

Ambil parameter secara berurutan p,x,n.

p (parameter 1) dalam urutan peningkatan derajat.

Jelas jika fdapat diambil sebagai fungsi ini dapat dikurangi hanya menjadi Nest.


Apakah Anda perlu membalikkan koefisien?
Giuseppe

@ Giuseppe Itu sebabnya ada Reversedalam kode.
user202729

@ user202729 Saya pikir Anda dapat mengambil koefisien dalam urutan apa pun yang Anda inginkan, baik naik atau turun.
Erik the Outgolfer

Kami percaya mereka diizinkan untuk meningkatkan atau menurunkan tingkat gelar. (Saya tidak tahu Mathematica sama sekali)
Giuseppe

Ya, Anda dapat mengambilnya dalam urutan yang diinginkan: dalam
Adám

4

Sekam , 5 byte

←↓¡`B

Cobalah online!

Gagasan utama di sini adalah bahwa mengevaluasi polinomial pada titik x setara dengan melakukan konversi basis dari basis x .

Bketika diberi basis dan daftar digit melakukan konversi basis. Di sini kita menggunakan versi terbalik, untuk mengambil daftar digit terlebih dahulu dan menerapkan fungsi ini sebagian. Kami mendapatkan kemudian fungsi yang menghitung nilai polinomial yang diberikan pada suatu titik, bagian kedua dari solusi ini berkaitan dengan iterasi fungsi ini jumlah yang benar kali:

Sekam , 3 byte

←↓¡

¡ adalah fungsi "iterate", dibutuhkan fungsi dan titik awal dan mengembalikan daftar nilai tak terhingga yang diperoleh dengan mengulangi fungsi tersebut.

mengambil nomor (argumen ketiga dari tantangan ini) dan menjatuhkan banyak elemen dari awal daftar.

mengembalikan elemen pertama dari daftar yang dihasilkan.



3

Ruby , 42 byte

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

C adalah daftar koefisien dalam urutan menurun

Versi sepele, di mana f adalah fungsi lambda ( 26 byte ):

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

Cobalah online!


3

JavaScript (ES6),  52 49 44  42 byte

Disimpan 5 byte berkat GB dan 2 byte lagi berkat Neil

Mengambil input dalam sintaks currying as (p)(n)(x), di mana p adalah daftar koefisien dalam urutan menurun.

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

Uji kasus


Jika p dalam urutan menurun, Anda dapat mengurangi menggunakan s * x + v dan mengabaikan i.
GB

Dalam hal itu, dapatkah Anda menghilangkan ,0dari pengurangan?
Neil

@Neil Tangkapan yang bagus. :-)
Arnauld

2

J , 15 byte

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

Cobalah online!

Mengambil polinomial sebagai daftar koefisien kekuatan naik.

Penjelasan

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

05AB1E , 10 9 byte

-1 byte terima kasih kepada Erik the Outgolfer

sF³gݨm*O

Cobalah online!

Mengambil x sebagai argumen pertama, n sebagai argumen kedua dan p dalam urutan naik sebagai argumen ketiga.

Penjelasan

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
Anda dapat menghapus yang kedua ³.
Erik the Outgolfer

Juga (This is in case n is 0 so x is on the stack)salah, Anda masih membutuhkan suntuk non-nol n.
Erik the Outgolfer

Ya itu benar. Saya berpikir lebih banyak di sepanjang baris penggantian ¹². Dengan sbegitu mendapat pekerjaan mendorong x ke stack dilakukan dalam 1 byte tanpa perlu mengulang setidaknya sekali. Mungkin seharusnya mengatakan itu lebih baik ^^ '. Juga terima kasih atas -1!
Datboi

Maksud saya, Anda masih akan membutuhkannya karena 05AB1E menggunakan input terakhir untuk input implisit jika semua input telah dibaca.
Erik the Outgolfer

" sF³gݨm³O" dan dalam penjelasannya juga ...
Erik the Outgolfer

2

Haskell , 15 byte

((!!).).iterate

Cobalah online!

Terima kasih untuk benar-benar manusia untuk 11 byte dari kedua solusi

Ini mendefinisikan fungsi diam-diam yang mengambil fungsi sebagai argumen pertama dan nsebagai argumen kedua, dan menyusun fungsi itu dengan nwaktu itu sendiri . Ini kemudian dapat disebut dengan argumen xuntuk mendapatkan nilai akhir. Berkat keajaiban currying, ini setara dengan satu fungsi yang mengambil tiga argumen.


Mengambil daftar koefisien alih-alih argumen fungsi:

Haskell , 53 byte

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

Cobalah online!

Ini sama dengan kode di atas, tetapi disusun dengan fungsi lambda yang mengubah daftar koefisien menjadi fungsi polinomial. Koefisien diambil dalam urutan terbalik dari contoh - sebagai kekuatan naik dari x.



TIO yang kedua harus mengambil daftar sebagai argumen, bukan fungsi;) Meskipun Anda dapat menyimpan beberapa byte dengan menggunakan lipatan seperti ini (perhatikan bahwa nol-polinomial tidak bisa []tetapi harus berupa sesuatu seperti [0]atau serupa ).
ბიმო

2

APL (Dyalog) , 20 9 byte

{⊥∘⍵⍣⎕⊢⍺}

Cobalah online!

Ini butuh x argumen kiri, koefisien fungsi sebagai argumen kanan, dan ndari STDIN.

Melihat ke belakang setelah sekian lama, saya menyadari saya bisa menyederhanakan perhitungan dengan menggunakan konversi basis .


APL (Dyalog), 5 byte

Jika kita dapat menggunakan fungsinya sebagai fungsi APL Dyalog, maka ini bisa menjadi 5 byte.

⎕⍣⎕⊢⎕

Mengambil x, ndan kemudian berfungsi sebagai input dari STDIN.


2

R , 96 58 55 52 byte

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

Cobalah online!

Penjelasan:

seq(p)menghasilkan daftar 1, 2, ..., length(p)kapan padalah vektor, demikian seq(p)-1pula eksponen polinomial, maka x^(seq(p)-1)setara dengan x^0(selalu sama dengan 1) , x^1, x^2, ...dan menghitung titik produk %*%dengan pmengevaluasi polinomial padax .

Selain itu, jika Pdiambil sebagai fungsi, maka ini akan menjadi 38 byte:

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

Dan tentu saja kita selalu dapat menghasilkan PdenganP=function(a)function(x)sum(x^(seq(a)-1)*a)



1

Python 3 , 70 69 byte

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

Membawa pdalam urutan menaik, yaitu jika padalah [0, 1, 2]maka sesuai polinomial adalah p(x) = 0 + 1*x + 2*x^2. Solusi rekursi sederhana.

Cobalah online!


1

C # (.NET Core) , 82 byte

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

Cobalah online!

Mengambil daftar koefisien dalam urutan yang berlawanan dari kasus uji (peningkatan urutan?) Sehingga indeks mereka dalam array sama dengan kekuatan x harus dinaikkan ke.

Dan versi sepele dalam 30 byte:

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

Cobalah online!

Membawa delegasi dan menerapkannya secara rekursif sebanyak n kali.


1

MATL , 11 byte

ii:"ZQ6Mw]&

Cobalah online!

Agak kurang menarik daripada jawaban Oktaf saya, meskipun saya pikir ada beberapa juggling input yang cerdas untuk memastikan n=0pekerjaan seperti yang diharapkan.


1

Julia 0.6.0 (78 bytes)

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

Penjelasan:

Paket Polinomial cukup jelas: ia menciptakan polinomial. Setelah itu rekursi yang cukup mendasar.

Untuk memiliki polinomial: -4.0 - 2.3 * x + 0.1 * x ^ 2 input aharus sepertia = [-4, -2.3, 0.1]


1

Aksioma, 91 byte

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)

bertakuk

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

input untuk polinomi g adalah satu daftar angka di kebalikan dari contoh latihan. sebagai contoh

[1,2,3,4,5]  

itu akan mewakili polinomi

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

uji:

(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 byte

Sebagai lambda tanpa nama generik, kembali melalui xParameter:

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

Tidak disatukan dan testcase:

#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 byte

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

Mengambil input sebagai

  • Jumlah iterasi
  • nilai awal x
  • Kemudian 3 bagian polinomial

Output sampel:

Command line: 8 2.3 0.1 -2.3 -4
 59.30772

0

Clojure, 66 byte

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

Contoh lengkap:

(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

Menyusun fungsi adalah 26 byte:

#(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 byte

Cukup mudah, melakukan apa yang dikatakan tantangan pada kaleng.

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.

Membawa masukan dalam rangka n, p, x.

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.