Oblicz n-tą iterację wielomianu dla określonej wartości; fⁿ (x)


19

Biorąc pod uwagę funkcję wielomianową f (np. Jako listę p rzeczywistych współczynników w porządku rosnącym lub malejącym), nieujemną liczbę całkowitą n i wartość rzeczywistą x , zwracamy:

   f n ( x )

tj. wartość f ( f ( f (… f ( x )…)))) dla n zastosowań f na x .

Używaj rozsądnej precyzji i zaokrąglania.

Rozwiązania, które przyjmują f jako listę współczynników, będą prawdopodobnie najciekawsze, ale jeśli jesteś w stanie przyjąć f jako rzeczywistą funkcję (zmniejszając w ten sposób wyzwanie do trywialnego „zastosuj funkcję n razy”), możesz ją uwzględnić po nietrywialnym rozwiązaniu.

Przykładowe przypadki

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



Czy moja odpowiedź Jelly może brać link Jelly i na przykład uważać go za „funkcję”?
Erik the Outgolfer

@EriktheOutgolfer Pierwotnie wymagałem danych wejściowych jako listy współczynników, aby zapobiec tak trywialnym rozwiązaniom. Jednak rozluźniłem to na życzenie. Proponuję opublikować wersję listy i dodać wersję trywialną jako notatkę (lub odwrotnie).
Adám

Już opublikowałem wersję listy, ale wersja funkcji jest znacznie krótsza.
Erik the Outgolfer

@EriktheOutgolfer Tak, oczywiście. Zobacz moją dodaną notatkę.
Adám

Odpowiedzi:


7

Oktawa , 49 bajtów

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

Wypróbuj online!

Lub przyjmując współczynniki:

Oktawa , 75 57 bajtów

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

Wypróbuj online!

Specjalne podziękowania dla Suever z StackOverflow za tę odpowiedź na moje pytanie, co dowodzi, że rekurencyjna anonimowa funkcja jest możliwa.

Definiuje to funkcję anonimową, która jest opakowaniem rekurencyjnej funkcji anonimowej ; coś, co nie jest natywną koncepcją Octave i wymaga pewnego fantazyjnego indeksowania macierzy komórek.

Jako bonus, druga wersja jest przyjemną lekcją na temat zmiennego zakresu w Octave. Wszystkie instancje rmogą być legalnie zastąpione przez f, które następnie po prostu nadpisują istniejące fw najbardziej lokalnym zakresie (podobnie dla n)

Wyjaśnienie

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

Kluczem do tego jest to, że anonimowe funkcje nie są oceniane, gdy są zdefiniowane. Tak więc, @()co wydaje się nieco zbędne, ponieważ definiuje anonimową funkcję, do której wywoływane jest ()bezpośrednio po, jest w rzeczywistości absolutnie konieczne. Nie jest wywoływany, chyba że zostanie wybrany przez instrukcję indeksowania.

Oktawa , 39 bajtów (nudny sposób)

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

Dla kompletności rozwiązanie Octave z najkrótszą liczbą bajtów. Ziewać. .


Spróbuję ponownie przeczytać to innym razem, ale wciąż nie rozumiem. Jako wielki fan Octave mogę tylko powiedzieć, świetna robota +1.
Michthan

2
@Michthan postaram się wyjaśnić lepiej, ale jest to jak dotąd najzwyklejsza oktawa, jaką napisałem - zwykle nazwy funkcji stanowią większość bajtów. To prawie Lisp.
Sanchises,

1
@Michthan Mam nadzieję, że nowe wyjaśnienie ma sens, patrząc na nie w widoku „rozstrzelonym”.
Sanchises,

4

Mathematica, 56 47 28 bajtów

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

\[Function] zajmuje 3 bajty w UTF-8.

Kolejność parametrów w kolejności p,x,n.

p (parametr 1) jest rosnący w kolejności stopni.

Oczywiście, jeśli fmożna to potraktować jako funkcję, można to zredukować tylko do Nest.


Czy potrzebujesz odwrócić współczynniki?
Giuseppe,

@Giuseppe Właśnie dlatego jest Reversew kodzie.
user202729,

@ user202729 Myślę, że możesz wziąć współczynniki w dowolnej kolejności, rosnącej lub malejącej.
Erik the Outgolfer

Uważam, że możemy przyjmować je w kolejności rosnącej lub malejącej. (W ogóle nie znam Matematyki)
Giuseppe

Tak, możesz posortować je w żądanej kolejności: w
Adám

4

Łuska , 5 bajtów

←↓¡`B

Wypróbuj online!

Kluczową ideą jest to, że ocena wielomianu w punkcie x jest równoważna przeprowadzeniu konwersji podstawy z podstawy x .

Bpo otrzymaniu bazy i listy cyfr dokonuje konwersji bazy. Tutaj używamy jego wersji odwróconej, aby najpierw pobrać listę cyfr i częściowo zastosować do niej tę funkcję. Otrzymujemy wtedy funkcję, która oblicza wartość danego wielomianu w punkcie, druga część tego rozwiązania dotyczy iteracji tej funkcji poprawną ilość razy:

Łuska , 3 bajty

←↓¡

¡ jest funkcją „iteracyjną”, bierze funkcję i punkt początkowy i zwraca nieskończoną listę wartości uzyskanych iterujących funkcję.

bierze liczbę (trzeci argument tego wyzwania) i upuszcza tyle elementów z początku listy.

zwraca pierwszy element wynikowej listy.



3

Rubin , 42 bajty

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

C to lista współczynników w kolejności malejącej

Trywialna wersja, gdzie f jest funkcją lambda ( 26 bajtów ):

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

Wypróbuj online!


3

JavaScript (ES6),  52 49 44  42 bajtów

Zaoszczędzono 5 bajtów dzięki GB i 2 kolejne bajty dzięki Neilowi

Pobiera dane wejściowe w składni curry jako (p)(n)(x), gdzie p jest listą współczynników w kolejności malejącej.

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

Przypadki testowe


Jeśli p jest w porządku malejącym, możesz zmniejszyć używając s * x + v i zignorować i.
GB

Czy w takim przypadku możesz pominąć ,0redukcję?
Neil

@Neil Good catch. :-)
Arnauld

2

J , 15 bajtów

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

Wypróbuj online!

Przyjmuje wielomian za listę współczynników rosnących mocy.

Wyjaśnienie

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 bajtów

-1 bajt dzięki Erik the Outgolfer

sF³gݨm*O

Wypróbuj online!

Pobiera x jako pierwszy argument, n jako drugi ip w porządku rosnącym jako trzeci.

Wyjaśnienie

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
Możesz usunąć drugi ³.
Erik the Outgolfer

Również (This is in case n is 0 so x is on the stack)jest źle, nadal potrzebujesz sdla niezerowej n.
Erik the Outgolfer

Tak to prawda. Zastanawiałem się nad zastąpieniem ¹²pliku .with, swięc zadanie polega na wypchnięciu x do stosu wykonanym w 1 bajcie bez potrzeby zapętlania przynajmniej raz. Prawdopodobnie powinienem to sformułować lepiej ^^. Również dziękuję za -1!
Datboi

Miałem na myśli, że nadal będziesz go potrzebować, ponieważ 05AB1E używa ostatniego wejścia do niejawnego wejścia, jeśli wszystkie dane zostały odczytane.
Erik the Outgolfer

sF³gݨm³O” oraz w wyjaśnieniach…
Erik Outgolfer

2

Haskell , 15 bajtów

((!!).).iterate

Wypróbuj online!

Dzięki totalnie ludzki za 11 bajtów off obu rozwiązań

Definiuje funkcję milczącą, która przyjmuje funkcję jako swój pierwszy argument i njako drugi argument, i tworzy tę funkcję ze sobą nrazy. Można to następnie wywołać za pomocą argumentu, xaby uzyskać końcową wartość. Dzięki magii curry jest to równoważne z jedną funkcją przyjmującą trzy argumenty.


Biorąc listę współczynników zamiast argumentu funkcji:

Haskell , 53 bajty

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

Wypróbuj online!

Jest to to samo, co powyższy kod, ale składa się z funkcji lambda, która konwertuje listę współczynników na funkcję wielomianową. Współczynniki są pobierane z przykładów w odwrotnej kolejności - jako rosnące moce x.



Tio z drugim powinien wziąć listę jako argumentu, a nie funkcji;) Choć można zaoszczędzić kilka bajtów za pomocą krotnie jak to (uwaga, że wielomian zero nie może być [], ale musi być coś takiego [0]lub podobnego ).
ბიმო

2

APL (Dyalog) , 20 9 bajtów

{⊥∘⍵⍣⎕⊢⍺}

Wypróbuj online!

Pobiera to xjako lewy argument, współczynniki funkcji jako prawy argument i nod STDIN.

Patrząc wstecz na to po wielu latach, zdałem sobie sprawę, że mogę uprościć obliczenia za pomocą konwersji podstawowej .


APL (Dyalog), 5 bajtów

Jeśli możemy przyjąć tę funkcję jako funkcję APL Dyalog, może to być 5 bajtów.

⎕⍣⎕⊢⎕

Pobiera x, na następnie funkcję jako dane wejściowe z STDIN.


2

R , 96 58 55 52 bajtów

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

Wypróbuj online!

Wyjaśnienie:

seq(p)generuje listę, 1, 2, ..., length(p)gdy pjest wektorem, podobnie seq(p)-1jak wykładniki wielomianu, a zatem x^(seq(p)-1)jest równoważny x^0(zawsze równy 1) , x^1, x^2, ...i obliczenie iloczynu %*%z pocenia wielomian przy x.

Dodatkowo, jeśli Pzostanie wzięty jako funkcja, będzie to 38 bajtów:

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

I oczywiście zawsze możemy generować PprzezP=function(a)function(x)sum(x^(seq(a)-1)*a)



1

Python 3 , 70 69 bajtów

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

Przyjmuje pw kolejności rosnącej, tzn. Jeśli pjest, [0, 1, 2]to odpowiedni wielomian to p(x) = 0 + 1*x + 2*x^2. Proste rozwiązanie rekurencyjne.

Wypróbuj online!


1

C # (.NET Core) , 82 bajty

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

Wypróbuj online!

Pobiera listę współczynników w kolejności odwrotnej do przypadków testowych (kolejność rosnąca?), Aby ich indeks w tablicy był równy potędze x.

A trywialna wersja w 30 bajtach:

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

Wypróbuj online!

Pobiera delegata i stosuje go rekurencyjnie n razy.


1

MATL , 11 bajtów

ii:"ZQ6Mw]&

Wypróbuj online!

Nieco mniej interesujące niż moja odpowiedź Octave, chociaż myślę, że jest pewne sprytne żonglowanie danymi wejściowymi, aby upewnić się, że n=0działa zgodnie z oczekiwaniami.


1

Julia 0.6.0 (78 bajtów)

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

Wyjaśnienia:

Pakiet Wielomiany jest dość oczywisty: tworzy wielomiany. Po tym jest to dość podstawowa rekurencja.

Aby uzyskać wielomian: -4,0 - 2,3 * x + 0,1 * x ^ 2, dane wejściowe amuszą być takie samea = [-4, -2.3, 0.1]


1

Aksjomat, 91 bajtów

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)

zębaty

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

Dane wejściowe dla polinomii g to jedna lista liczb na odwrocie przykładu ćwiczenia. na przykład

[1,2,3,4,5]  

reprezentowałby polinomię

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

test:

(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 bajtów

Jako ogólna nienazwana lambda, zwracana przez xparametr:

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

Niekluczone i 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 bajtów

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

Przyjmuje dane wejściowe jako

  • Liczba iteracji
  • wartość początkowa x
  • Następnie 3 części wielomianu

Przykładowe dane wyjściowe:

Command line: 8 2.3 0.1 -2.3 -4
 59.30772

0

Clojure, 66 bajtów

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

Pełny przykład:

(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

Skomponowanie funkcji ma 26 bajtów:

#(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 bajtów

Całkiem proste, robi to, co mówi wyzwanie na puszce.

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.

Staje wejść w porządku n, p, x.

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.