Calculer le n-ième itération d'un polynôme pour une valeur spécifique; fⁿ (x)


19

Étant donné une fonction polynomiale f (par exemple sous la forme d'une liste p de coefficients réels dans l'ordre croissant ou décroissant), un entier non négatif n et une valeur réelle x renvoient:

   f n ( x )

soit la valeur de f ( f ( f (… f ( x )…))) pour n applications de f sur x .

Utilisez une précision et un arrondi raisonnables.

Les solutions qui prennent f comme liste de coefficients seront probablement les plus intéressantes, mais si vous êtes capable de prendre f comme fonction réelle (réduisant ainsi ce défi au trivial "appliquer une fonction n fois"), n'hésitez pas à l'inclure après votre solution non triviale.

Exemples de cas

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



Ma réponse Jelly peut-elle prendre un lien Jelly et le considérer comme une "fonction", par exemple?
Erik the Outgolfer

@EriktheOutgolfer Au départ, j'avais besoin d'une entrée sous forme de liste de coefficients afin d'éviter de telles solutions triviales. Cependant, je l'ai assoupli sur demande. Je vous suggère de publier la version de la liste et d'ajouter la version triviale en tant que note (ou opposée).
Adám

J'ai déjà publié la version de liste, mais la version de fonction est beaucoup plus courte.
Erik the Outgolfer

@EriktheOutgolfer Oui, évidemment. Voir ma note ajoutée.
Adám

Réponses:


7

Octave , 49 octets

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

Essayez-le en ligne!

Ou, en prenant des coefficients:

Octave , 75 57 octets

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

Essayez-le en ligne!

Un merci spécial pour Suever sur StackOverflow, pour cette réponse il y a quelque temps sur une de mes questions, prouvant qu'une fonction anonyme récursive est possible.

Ceci définit une fonction anonyme, qui est un wrapper pour une fonction anonyme récursive ; quelque chose qui n'est pas un concept natif d'Octave, et qui nécessite une indexation de tableau de cellules sophistiquée.

En bonus, la deuxième version est une belle leçon de cadrage variable dans Octave. Toutes les instances de rpeuvent légalement être remplacées par f, qui remplacent alors simplement l'existant fdans la portée la plus locale (similaire pour n)

Explication

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

La clé de ceci est que les fonctions anonymes ne sont pas évaluées lorsqu'elles sont définies. Ainsi, le @(), qui semble un peu superflu puisqu'il définit une fonction anonyme qui est appelée ()directement après, est en fait strictement nécessaire. Il n'est appelé que s'il est sélectionné par l'instruction d'indexation.

Octave , 39 octets (façon ennuyeuse)

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

Juste pour être complet, la solution Octave avec le bytecount le plus court. Bâillement. .


Je vais essayer de relire cela une autre fois, mais je ne comprends toujours pas très bien .. En tant que grand fan d'Octave, je peux seulement dire, excellent travail +1.
Michthan

2
@Michthan Je vais essayer de faire une meilleure explication, mais c'est de loin l'octave la plus laconique que j'ai écrite - généralement, les noms de fonction représentent la majorité du nombre d'octets. C'est presque Lisp.
Sanchises

1
@Michthan J'espère que la nouvelle explication a un certain sens, en la regardant dans une vue «éclatée».
Sanchises

4

Mathematica, 56 47 28 octets

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

\[Function] prend 3 octets en UTF-8.

Prenez les paramètres dans l'ordre p,x,n.

p (paramètre 1) est en ordre croissant de degré.

Évidemment, si cela fpeut être considéré comme une fonction, cela peut être réduit à Nest.


Devez-vous inverser les coefficients?
Giuseppe

@Giuseppe C'est pourquoi il y en a Reversedans le code.
user202729

@ user202729 Je pense que vous pouvez prendre les coefficients dans l'ordre de votre choix, ascendant ou descendant.
Erik the Outgolfer

Nous sommes autorisés à les prendre par ordre croissant ou décroissant de degré, je crois. (Je ne connais pas du tout Mathematica)
Giuseppe

Oui, vous pouvez les prendre dans l'ordre souhaité: dans l'ordre croissant ou décroissant
Adám

4

Husk , 5 octets

←↓¡`B

Essayez-le en ligne!

L'idée clé ici est que l'évaluation d'un polinôme en un point x équivaut à effectuer une conversion de base à partir de la base x .

Bquand on leur donne une base et une liste de chiffres, la conversion de base est effectuée. Ici, nous utilisons sa version inversée, afin de prendre d'abord la liste des chiffres et de lui appliquer partiellement cette fonction. Nous obtenons alors une fonction qui calcule la valeur du polynôme donné en un point, la deuxième partie de cette solution traite de l'itération de cette fonction la quantité de temps correcte:

Husk , 3 octets

←↓¡

¡ est la fonction "itérer", elle prend une fonction et un point de départ et retourne la liste infinie de valeurs obtenues en itérant la fonction.

prend un nombre (le troisième argument de ce défi) et supprime autant d'éléments depuis le début de la liste.

renvoie le premier élément de la liste résultante.



3

Rubis , 42 octets

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

C est la liste des coefficients par ordre décroissant

Version triviale, où f est une fonction lambda ( 26 octets ):

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

Essayez-le en ligne!


3

JavaScript (ES6),  52 49 44  42 octets

5 octets enregistrés grâce à Go et 2 octets supplémentaires grâce à Neil

Prend l'entrée dans la syntaxe de curry comme (p)(n)(x), où p est la liste des coefficients dans l'ordre décroissant.

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

Cas de test


Si p est dans l'ordre décroissant, vous pouvez réduire en utilisant s * x + v et ignorer i.
GB

Dans ce cas, pouvez-vous omettre le ,0de la réduction?
Neil

@Neil Bonne prise. :-)
Arnauld

2

J , 15 octets

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

Essayez-le en ligne!

Prend le polynôme comme une liste de coefficients de puissances ascendantes.

Explication

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 octets

-1 octet grâce à Erik l'Outgolfer

sF³gݨm*O

Essayez-le en ligne!

Prend x comme premier argument, n comme deuxième et p dans l'ordre croissant comme troisième.

Explication

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
Vous pouvez supprimer le second ³.
Erik the Outgolfer

Aussi (This is in case n is 0 so x is on the stack) faux, vous avez toujours besoin de spour n différent de zéro.
Erik the Outgolfer

Ouais c'est vrai. Je pensais plus à remplacer¹² .with spour obtenir le travail de pousser x vers la pile en 1 octet sans avoir besoin de boucler au moins une fois. J'aurais probablement dû formuler cela mieux ^^ '. Merci aussi pour le -1!
Datboi

Je voulais dire que vous en auriez toujours besoin car 05AB1E utilise la dernière entrée pour une entrée implicite si toutes les entrées ont été lues.
Erik the Outgolfer

" sF³gݨm³O" et dans l'explication aussi ...
Erik the Outgolfer

2

Haskell , 15 octets

((!!).).iterate

Essayez-le en ligne!

Merci à totalement humain pour 11 octets hors des deux solutions

Cela définit une fonction tacite qui prend une fonction comme premier argument et ncomme deuxième argument, et compose cette fonction avec elle-même n. Cela peut ensuite être appelé avec un argument xpour obtenir la valeur finale. Grâce à la magie du curry, cela équivaut à une fonction prenant trois arguments.


Prendre une liste de coefficients au lieu d'un argument de fonction:

Haskell , 53 octets

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

Essayez-le en ligne!

C'est le même que le code ci-dessus, mais composé d'une fonction lambda qui convertit une liste de coefficients en une fonction polynomiale. Les coefficients sont pris dans l'ordre inverse des exemples - en tant que puissances ascendantes dex .



Le TIO du second doit prendre une liste comme argument, pas une fonction;) Bien que vous puissiez enregistrer une poignée d'octets en utilisant un pli comme celui-ci (notez que le polynôme zéro ne peut pas être []mais doit être quelque chose comme [0]ou similaire ).
ბიმო

2

APL (Dyalog) , 20 9 octets

{⊥∘⍵⍣⎕⊢⍺}

Essayez-le en ligne!

Cela prend xcomme argument de gauche, les coefficients de la fonction comme argument de droite, et nde STDIN.

En y repensant après bien longtemps, j'ai réalisé que je pouvais simplifier le calcul en utilisant la conversion de base .


APL (Dyalog), 5 octets

Si nous pouvons prendre la fonction comme une fonction Dyalog APL, cela peut être de 5 octets.

⎕⍣⎕⊢⎕

Prend x, npuis la fonction comme entrée de STDIN.


2

R , 96 58 55 52 octets

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

Essayez-le en ligne!

Explication:

seq(p)génère la liste 1, 2, ..., length(p)quand pest un vecteur, tout seq(p)-1comme les exposants du polynôme, x^(seq(p)-1)est donc équivalent à x^0(toujours égal à 1) , x^1, x^2, ...et à calculer un produit scalaire %*%avecp évalue le polynôme à x.

De plus, si Pest considéré comme une fonction, ce serait 38 octets:

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

Et nous pouvons bien sûr toujours générer PparP=function(a)function(x)sum(x^(seq(a)-1)*a)



1

Python 3 , 70 69 octets

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

Prend pen ordre croissant, c'est-à-dire sip est [0, 1, 2]alors le polynôme correspondant est p(x) = 0 + 1*x + 2*x^2. Solution de récursivité simple.

Essayez-le en ligne!


1

C # (.NET Core) , 82 octets

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

Essayez-le en ligne!

Prend une liste de coefficients dans l'ordre inverse des cas de test (ordre croissant?) De sorte que leur indice dans le tableau soit égal à la puissance x doit être augmentée.

Et la version triviale en 30 octets:

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

Essayez-le en ligne!

Prend un délégué et l'applique récursivement n fois.


1

MATL , 11 octets

ii:"ZQ6Mw]&

Essayez-le en ligne!

Un peu moins intéressant que ma réponse Octave, bien que je pense qu'il y ait un jonglage intelligent des entrées pour s'assurer que cela n=0fonctionne comme prévu.


1

Julia 0.6.0 (78 octets)

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

Explications:

Le package Polynômes est assez explicite: il crée des polynômes. Après c'est une récursion assez basique.

Pour avoir un polynôme: -4,0 - 2,3 * x + 0,1 * x ^ 2, l'entrée adoit être commea = [-4, -2.3, 0.1]


1

Axiome, 91 octets

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)

dentelé

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

l'entrée pour la polynomie g c'est une liste de nombres à l'inverse de l'exemple d'exercice. par exemple

[1,2,3,4,5]  

cela représenterait la polinomie

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

tester:

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

En tant que lambda générique sans nom, renvoyant via le xparamètre:

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

Ungolfed et 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 octets

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

Prend les entrées comme

  • Nombre d'itérations
  • valeur de départ de x
  • Puis les 3 parties du polynôme

Exemple de sortie:

Command line: 8 2.3 0.1 -2.3 -4
 59.30772

0

Clojure, 66 octets

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

Exemple complet:

(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

La composition d'une fonction est de 26 octets:

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

Assez simple, fait ce que le défi dit sur l'étain.

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.

Prend des entrées pour n, p, x.

Essayez-le en ligne!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.