Обчисліть n-й ітерат многочлена для конкретного значення; fⁿ (x)


19

Враховуючи поліноміальну функцію f (наприклад, як список p реальних коефіцієнтів у порядку зростання чи зменшення), невід'ємне ціле число n та дійсне значення x повертають:

   f n ( x )

тобто значення f ( f ( f (… f ( x )…))) для n застосувань f на x .

Використовуйте розумну точність і округлення.

Рішення, які приймають 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



Чи може моя відповідь Jelly взяти посилання на Jelly і вважати це, наприклад, "функцією"?
Erik the Outgolfer

@EriktheOutgolfer Я спочатку вимагав введення як списку коефіцієнтів для запобігання таких тривіальних рішень. Однак я розслабила це на прохання. Я пропоную вам опублікувати список версій і додати тривіальну версію як примітку (або навпаки).
Адам

Я вже опублікував версію списку, але версія функції набагато коротша.
Erik the Outgolfer

@EriktheOutgolfer Так, очевидно. Дивіться мою додану примітку.
Адам

Відповіді:


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.
Міхтан

2
@Michthan Я спробую зробити краще пояснення, але це, безумовно, найкоротша Октава, яку я написав - зазвичай, імена функцій - це більшість підрахунків байтів. Це майже Лісп.
Санчіз

1
@Michthan Сподіваємось, нове пояснення має певний сенс, дивлячись на це у "вибухнутому" погляді.
Санчіз

4

Математика, 56 47 28 байт

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

\[Function] займає 3 байти в UTF-8.

Візьміть параметри по порядку p,x,n.

p (параметр 1) в порядку збільшення ступеня.

Очевидно, що якщо fїх можна взяти за функцію, це може бути зведено просто до Nest.


Чи потрібно повернути коефіцієнти?
Джузеппе

@Giuseppe Ось чому є Reverseв коді.
користувач202729

@ user202729 Я думаю, що ви можете приймати коефіцієнти в будь-якому порядку, який ви хочете, або зростаючим, або спадаючим.
Erik the Outgolfer

Нам дозволяється приймати їх у порядку збільшення чи зменшенні ступеня. (Я не знаю Mathematica взагалі)
Джузеппе

Так, ви можете прийняти їх у бажаному порядку: у порядку зростання чи зменшення
Adám

4

Лушпиння , 5 байт

←↓¡`B

Спробуйте в Інтернеті!

Ключова ідея тут полягає в тому, що оцінювання полінома в точці x еквівалентно перетворенню базового перетворення з бази x .

Bколи дано базу і список цифр, виконує перетворення бази. Тут ми використовуємо його перевернуту версію, щоб спочатку взяти список цифр і частково застосувати до нього цю функцію. Тоді ми отримуємо функцію, яка обчислює значення даного многочлена в точці, друга частина цього рішення стосується ітерації цієї функції в правильну кількість разів:

Лушпиння , 3 байти

←↓¡

¡ є функцією "ітерація", вона приймає функцію і вихідну точку і повертає нескінченний список значень, отриманих ітерацією функції.

приймає число (третій аргумент цього виклику) і скидає багато елементів із початку списку.

повертає перший елемент отриманого списку.



3

Рубін , 42 байти

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

C - перелік коефіцієнтів у порядку зменшення

Тривіальна версія, де f - лямбда-функція ( 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 байт

Збережено 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.
ГБ

У такому випадку ви можете пропустити ,0зменшення?
Ніл

@Neil Хороший улов. :-)
Арнольд

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

05AB1E , 10 9 байт

-1 байт завдяки Еріку Переможнику

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

Також (This is in case n is 0 so x is on the stack)неправильно, вам все одно потрібна sn-нуль n.
Erik the Outgolfer

Так, це правда. Я думав більше по лінії заміни ¹².with sтаким чином, це отримує завдання підштовхувати х до стека, виконаного в 1 байт, не потребуючи циклу хоча б раз. Напевно, мав би сказати, що краще ^^ '. Також дякую за -1!
Датбой

Я мав на увазі, що вам все одно знадобиться, оскільки 05AB1E використовує останній вхід для неявного введення, якщо всі входи були прочитані.
Erik the Outgolfer

" sF³gݨm³O" і в поясненні теж ...
Ерік Вигнавець

2

Haskell , 15 байт

((!!).).iterate

Спробуйте в Інтернеті!

Завдяки абсолютно нелюдським за 11 байт від обох рішень

Це визначає мовчазну функцію, яка приймає функцію як перший аргумент і nяк другий аргумент і складається цю функцію із самих nразів. Потім це можна викликати аргументом, xщоб отримати остаточне значення. Завдяки магії каррінга це еквівалентно одній функції, яка бере три аргументи.


Візьмемо список коефіцієнтів замість аргументу функції:

Haskell , 53 байти

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

Спробуйте в Інтернеті!

Це те саме, що і в наведеному вище коді, але складається з лямбда-функції, яка перетворює список коефіцієнтів у поліноміальну функцію. Коефіцієнти приймаються у зворотному порядку з прикладів - як зростаючі сили x.



TIO з другого слід взяти список в якості аргументу, а не функція;) Хоча ви можете зберегти кілька байтів, використовуючи згин як цього (зауважимо , що нульовий многочлен може не бути , []але має бути що - щось на зразок [0]або подібне ).
ბიმო

2

APL (Dyalog) , 20 9 байт

{⊥∘⍵⍣⎕⊢⍺}

Спробуйте в Інтернеті!

Це приймає xяк лівий аргумент, коефіцієнти функції як правий аргумент, а nвід STDIN.

Озираючись на це після багатьох довгих років, я зрозумів, що можу спростити обчислення за допомогою базового перетворення .


APL (Dyalog), 5 байт

Якщо ми можемо прийняти функцію як функцію APL Dyalog, то це може бути 5 байт.

⎕⍣⎕⊢⎕

Бере x, nа потім функцію як вхід з STDIN.


2

R , 96 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

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

Спробуйте в Інтернеті!

Бере перелік коефіцієнтів у протилежному порядку від тестових випадків (збільшуючи порядок?), Щоб їх індекс у масиві дорівнював потужності х, до якої слід підняти.

І тривіальна версія в 30 байт:

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

Спробуйте в Інтернеті!

Бере делегата і застосовує його рекурсивно n разів.


1

MATL , 11 байт

ii:"ZQ6Mw]&

Спробуйте в Інтернеті!

Трохи менш цікавий, ніж моя відповідь Октави, хоча я думаю, що є кілька розумних жонглювань вхідними даними, щоб переконатися, що n=0працює, як очікувалося.


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 байт

Як загальна безіменна лямбда, повертаючись через xПараметр:

[](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.

Приймає вхідні сигнали в порядку n, p, x.

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.