Approximer le nombre de Dottie

13

Le nombre de Dottie est le point fixe de la fonction cosinus, ou la solution de l'équation cos (x) = x . 1

Votre tâche sera de créer un code qui se rapproche de cette constante. Votre code doit représenter une fonction qui prend un entier en entrée et génère un nombre réel. La limite de votre fonction à mesure que l'entrée augmente doit être le nombre Dottie.

Vous pouvez produire une fraction, une décimale ou une représentation algébrique d'un nombre. Votre sortie doit pouvoir être arbitrairement précise, les flottants et les doubles ne sont pas suffisants pour relever ce défi. Si votre langue n'est pas capable de nombres de précision arbitraires, vous devez alors les implémenter ou choisir une nouvelle langue.

Il s'agit d'une question de donc les réponses seront notées en octets, avec moins d'octets étant mieux.

Conseils

Une façon de calculer la constante consiste à prendre n'importe quel nombre et à lui appliquer à plusieurs reprises le cosinus. Comme le nombre d'applications tend vers l'infini, le résultat tend vers le point fixe du cosinus.

Voici une approximation assez précise du nombre.

0.739085133215161

1: Ici, nous prendrons le cosinus en radians

Post Rock Garf Hunter
la source
Donc, si nous utilisons Python, nous devons implémenter notre propre type ou importer Decimal?
M. Xcoder
Quelle doit être l'exactitude de nos soumissions?
M. Xcoder
Accède au didacticiel Jelly pour voler se ÆẠȷ¡rend compte qu'il n'est pas valide. Essaie Brachylog; oh non Brachylog ne fait même pas de flotteurs.
Erik the Outgolfer
@ Mr.Xcoder Ils doivent uniquement être asymptotiquement précis.
Post Rock Garf Hunter
1
Je voudrais voir cela dans Haskell, APL et un peu de saveur Lisp.
Mark C

Réponses:

6

MATL , 34 30 19 octets

11 octets grâce à Sanchises !

48i:"'cos('wh41hGY$

Le dernier chiffre décimal dans la sortie peut être désactivé. Cependant, le nombre de chiffres corrects partant de la gauche augmente avec l'entrée et le résultat converge vers la constante réelle.

Essayez-le en ligne!

Explication

Pour l'entrée n et à partir de x = 1, cela applique la fonction

              x ↦ cos ( x )

avec n- chiffres arithmétiques à précision variable n fois.

48         % Push 48, which is ASCII for '1': initial value for x as a string
i:"        % Do n times, where n is the input
  'cos('   %   Push this string
  w        %   Swap. Moves current string x onto the top of the stack
  h        %   Concatenate
  41       %   Push 41, which is ASCII for ')'
  h        %   Concatenate. This gives the string 'cos(x)', where x is the
           %   current number
  GY$      %   Evaluate with variable-prevision arithmetic using n digits
           %   The result is a string, which represents the new x
           % End (implicit). Display (implicit). The stack contains the last x
Luis Mendo
la source
Pourquoi ne pas simplement l'appliquer n fois avec une précision de n chiffres? Cela semble trop compliqué.
Sanchises
C'est incroyable. Je veux le voir dans APL.
Mark C
3

PHP , 50 octets

$a=$argv[1];$i=$j=0;while($i<$a){$j=cos($j);$i++;}

Essayez-le en ligne!

Alex Neises
la source
Bienvenue sur le site! :)
James
Je pense que for($a=$argv[1];$a--;)$j=cos($j);echo$j;(40 octets) est suffisant.
Ismael Miguel
3

GNU bc -l, 30

Le score inclut +1 pour le -ldrapeau à bc.

for(a=1;a/A-b/A;b=c(a))a=b
a

La nouvelle ligne finale est importante et nécessaire.

Essayez-le en ligne .

-l fait 2 choses:

  • activer la bibliothèque "math", y compris c() pour cos (x)
  • définit la précision (échelle) à 20 décimales ( bca un calcul de précision arbitraire)

Je ne suis pas vraiment clair sur l'exigence de précision. En l'état, ce programme calcule jusqu'à 20 décimales. Si une précision différente est requise, elle scale=n;doit être insérée au début du programme, où nest le nombre de décimales. Je ne sais pas si je dois ajouter ceci à mon score ou non.

Notez également que pour certains nombres de décimales (par exemple 21, mais pas 20), le calcul oscille de chaque côté de la solution dans le dernier chiffre. Ainsi, dans la comparaison des itérations actuelles et précédentes, je divise les deux côtés par 10 ( A) pour effacer le dernier chiffre.

Traumatisme numérique
la source
3

Mathematica, 22 octets

Nest[Cos@#&,0,9#]~N~#&

contribution

[100]

production

0,73908513321516064165531208767387340401341175890075746496568063577328 \ 46548835475945993761069317665318

J42161217
la source
2

R (+ Rmpfr), 55 octets

function(n,b=Rmpfr::mpfr(1,n)){for(i in 1:n)b=cos(b);b}

Dennis a maintenant ajouté Rmpfr à TIO donc cela fonctionnera; ajouté quelques cas de test.

Explication:

Prend le code que j'ai écrit de ce défi pour évaluer les cos ntemps à partir 1, mais d' abord je précise la précision que je veux que les valeurs à être en en créant un objet bde classe mpfravec la valeur 1et la précision n, n>=2afin que nous obtenons plus de précision que nous avançons.

Essayez-le en ligne!

Giuseppe
la source
3
Réessayer. :) À l'avenir, si quelque chose manque à TIO, n'hésitez pas à laisser un message sur talk.tryitonline.net .
Dennis
@Dennis Merci! Je garderai cela à l'esprit à l'avenir!
Giuseppe
1

Mathics or Mathematica, 46 bytes

{$MaxPrecision=#}~Block~Cos~FixedPoint~N[1,#]&

Try it online!

notjagan
la source
1

K: 6 bytes

  _cos/1
0.7390851

f/ applies f until it reaches a fixed point.

tangentstorm
la source
0

Python - 89 bytes

Uses decimal module.

from decimal import*
import math
lambda n:reduce(lambda a,b:Decimal(math.cos(a)),[1]*n,1)
Maltysen
la source
84 bytes by combining imports.
Arnold Palmer
0

Perl 5, 41 Bytes

use bignum;sub f{$_[0]?cos(f($_[0]-1)):0}

Bignum is required for the arbitrary precision. Defines a function f that recursively applies cosine to 0 N times.

TIO doesn't seem to have bignum so no link :(

theLambGoat
la source
0

Mathematica 44 Bytes

FindRoot[Cos@x-x,{x,0},WorkingPrecision->#]&

FindRoot uses Newton's method by default.

Kelly Lowder
la source
0

Python 2, 86 bytes

import math as m,decimal as d
def f(x,n):return f(d.Decimal(m.cos(x)),n-1)if n else x

New version using the tip provided.

Python 2, 105 bytes

import math as m,decimal as d
def f(x,n):return d.Decimal(f(x+(m.cos(x)-x)/(m.sin(x)+1),n-1))if n else x

Uses Newton's method and recursive function to calculate the value. x is initial value and n is the recursion limit.

SydB
la source
Python's builtin float type does have indefinite precision, thus your function is not actually asymptotic.
Post Rock Garf Hunter
Thanks, good to know. Fixed I guess, not very short anymore tho :)
SydB
L'astuce fournie dans la question serait probablement plus courte que la méthode de Newton.
Post Rock Garf Hunter
Merci encore, il me semble que j'étais trop emporté par les mathématiques fantaisistes.
SydB
0

Axiome, 174 octets

f(n:PI):Complex Float==(n>10^4=>%i;m:=digits(n+10);e:=10^(-n-7);a:=0;repeat(b:=a+(cos(a)-a)/(sin(a)+1.);if a~=0 and a-b<e then break;a:=b);a:=floor(b*10^n)/10.^n;digits(m);a)

non golfé et commenté

-- Input: n:PI numero di cifre
-- Output la soluzione x a cos(x)=x con n cifre significative dopo la virgola
-- Usa il metodo di Newton a_0:=a  a_(n+1)=a_n-f(a_n)/f'(a_n)
fo(n:PI):Complex Float==
  n>10^4=>%i
  m:=digits(n+10)
  e:=10^(-n-7)
  a:=0     -- Punto iniziale
  repeat
     b:=a+(cos(a)-a)/(sin(a)+1.)
     if a~=0 and a-b<e then break
     a:=b
  a:=floor(b*10^n)/10.^n
  digits(m)
  a

résultats:

(3) -> for i in 1..10 repeat output[i,f(i)]
   [1.0,0.7]
   [2.0,0.73]
   [3.0,0.739]
   [4.0,0.739]
   [5.0,0.73908]
   [6.0,0.739085]
   [7.0,0.7390851]
   [8.0,0.73908513]
   [9.0,0.739085133]
   [10.0,0.7390851332]
                                                               Type: Void
           Time: 0.12 (IN) + 0.10 (EV) + 0.12 (OT) + 0.02 (GC) = 0.35 sec
(4) -> f 300
   (4)
  0.7390851332 1516064165 5312087673 8734040134 1175890075 7464965680 635773284
  6 5488354759 4599376106 9317665318 4980124664 3987163027 7149036913 084203157
  8 0440574620 7786885249 0389153928 9438845095 2348013356 3127677223 158095635
  3 7765724512 0437341993 6433512538 4097800343 4064670047 9402143478 080271801
  8 8377113613 8204206631
                                                      Type: Complex Float
                                   Time: 0.03 (IN) + 0.07 (OT) = 0.10 sec

J'utiliserais la méthode Newton car elle serait plus rapide que la «méthode cos (x) répétée»

 800   92x
1000  153x
2000  379x

où dans la première colonne il y a le nombre de chiffres et dans la deuxième colonne il y a combien la méthode de Newton est plus rapide que d'utiliser la méthode cos (x) répétée, ici. Bonjour

RosLuP
la source